Окно дерева объектов delphi

1.3. Окно Конструктора формы

Форма – заготовка для разрабатываемого приложения. Здесь должны размещаться компоненты.

  • Заголовок с именем по соглашению Form. При создании проекта форме лучше давать осмысленное имя, отражающее функцию приложения.
  • Поле формы с координатной разметкой. В него заносятся компоненты, выбираемые из панели компонент.

Вид при старте Delphi. Вид после заполнения формы компонентами.

1.4. Окно Дерево объектов

Содержит перечень объектов формы в виде иерархического дерева. Слева вид окна при старте программы, дерево объектов содержит пустую форму. Справа окно для созданного проекта. В нем форма содержит вложенные компоненты. Внимание. В разных русифицированных версиях Delphi окно называется по разному.

1.5. Окно инспектора объектов

Обычно размещается слева от окна формы. Рекомендуется не заслонять окно другими окнами, так как оно часто требуется. В окне отображаются сведения о выделенном в форме компоненте. Содержит:

  • заголовок,
  • список объектов формы для выбора в виде комбинированного списка,
  • страницу свойств выделенного объекта (слева),
  • страницу обрабатываемых событий выделенного объекта (справа).

Страница свойств Страница событий Свойства представлены с группированием по категориям, с возможностью раскрытия групп. Значок плюс/минус — признак группы. Значок плюс обозначает, что группа не раскрыта, а минус, что она раскрыта.

1.6. Окно редактора кода

Редактор кода предназначен для создания кода модуля формы программы. Обычно позиционируется там же, где окно Конструктора формы, чтобы не занимать на экране лишнего места. Переключение окон Форма/Модуль клавишей F12. Можно эти окна разместить рядом. Слева к окну редактора кода обычно приклеивается панель Проводник кода, содержащий иерархически организованный перечень объявлений модуля. Его можно отключить. Редактор кода содержит:

  • заголовок с именем Unit.
  • вспомогательное окно проводника кода (слева с иерархическим представлением),
  • панель редактора с линейками прокрутки,
  • строку состояния внизу для информирования программиста о событиях.

Текст кода модуля выводится с синтаксическими выделениями. По соглашению:

  • Зарезервированные слова языка Delphi полужирным шрифтом.
  • Комментарии курсивом и синим цветом.
  • Директивы компилятора зеленым цветом.

1.7. Структура программ Delphi

1.7.1. Введение 1.7.2. Консольное приложение 1.7.3. Приложение

1.7.1. Введение

  • Консольное приложение. Имитация работы под операционной системой DOS в режиме командной строки. Нет графики.
  • Приложение. Программа под Windows.
  • CLX приложение. Можно выбрать Windows или Linux.
Читайте также:  Виды структуры данных дерево

Источник

Окно дерева объектов delphi

TreeView довольно удобный компонент для создания иерархических структур.
Это может быть абсолютно любой набор данных, в котором есть родительский и подчиненные узлы.
В этой статье будет рассмотрен процесс наполнения дерева данными из БД, таблицы которой связаны по внешнему ключу определяемому разработчиком.
В приведенном ниже примере рассмотрим ручное наполнение TreeView и наполение с помощью запросов к базе данных, визуальное оформление и формирование данных передаваемых узлом. В данном примере используются как первичный(primary key), так и вторичный или внешний (foreign key) ключ записи.
Для соединения с базой MySQL я использую компоненты из набора Zeos (ZConnection).
Определившись с постановкой задачи начинаем ваять проект.
Положим на форму компонент TreeView (в моем случае это sTreeView — не принципиально) и добавим компоненты для связи с БД и компонент ImageList, в котором будем хранить нужные для отображения в узлах дерева картинки.
Изображение с индексом =0 используется для всех узлов по умолчанию, поэтому при наполнении дерева необходимо узлам назначать изображения, если хотите видеть разные в различных пунктах. Сразу замечу, что назначив изображения пунктам дерева с помощью параметра node.ImageIndex, — вы не избавитесь от его автоматической замены на картинку с индексом=0 из ImageList, — для этого необходимо использовать для узла параметр node.SelectedIndex равный ImageIndex выбранный для узла.
В рассмотреном примере Вы увидите как выделить доступный узел среди всех остальных. Для начала объявим переменные и типы которые будут использоваться:

var Form1: TForm1; Node: TTreeNode; pch_node,pd_node:ttreenode; cur_pch,cur_pd,user_pch,user_pd,i,j:integer;

Здесь pch_node — узел верхнего уровня, pd_node — подчиненные узлы.
cur_pch — будет использовано для получения кода главного узла
cur_pd — будет использовано для получения кода подчиненного объекта
user_pch,user_pd — коды, в данном случае, предприятия и цеха определенные заранее для пользователя.

Для облегчения восприятия этой статьи рассмотрим сначала простой пример дерева с прикрепленными изображениями.
Построение дерева будет таким:

//Корневой узел pch_node:= sTreeView1.Items.Add(nil,'Главный узел'); pch_node.Data:=Pointer(1);pch_node.ImageIndex:=2; pch_node.SelectedIndex:=2; //Вложенные узлы pd_node:= sTreeView1.Items.AddChild(pch_node,'Подчиненный-1'); pd_node.Data:=Pointer(11); pd_node:= sTreeView1.Items.AddChild(pch_node,'Подчиненный-2'); pd_node.Data:=Pointer(12); pd_node.ImageIndex:=1; pd_node:= sTreeView1.Items.AddChild(pch_node,'Подчиненный-3'); pd_node.Data:=Pointer(13);

Обратите внимание на использование ImageIndex и SelectedIndex.
В первой строке им заданы значения и они равны — это даст для верхнего уровня иконку из ImageList с индексом 2 и указывает, что при выборе этого узла дерева иконка останется та же.
Во второй и четвертой строках эти параметры не заданы — следовательно они в любом случае будут отображатся с картинкой заданной индексом равным нулю.
Третья строка нам показывает, что для узла задана иконка с индексом равным 1 , но не задано значение SelectedIndex, а значит при выборе этого узла, — его иконка заменится на иконку с индексом = 0.
Если Вы внимательно следите за текстом, то наверняка заметили, что ничего не сказано про параметр .Data:=Pointer()
Этим кодом для объекта дерева присваеваем ему некое значение, в данном случае ключ, которое будет получено при его выборе.
Со структурой дерева и некоторыми его параметрами определились.
Теперь научимся связывать БД с TreeView.
Данные о предприятии (в этом примере) находятся в одной таблице базы данных, а данные по цехам предприятий — в другой. Связь между таблицами я организовал через использование первичного и вторичного ключей.
Так, в таблице предприятий есть поле FK, содержащее номер предприятия,а в таблице цехов предприятия поле pkpch — содержащее номер предприятия, их и слинковываю.
*
Конечно было бы правильнее связывать поле pkpch из таблицы цехов (таблица с именем pd) с первичным ключем таблицы предприятий (таблица с именем pch), но я допустил ошибку при заполнении таблицы цехов вписав в поле pkpch таблицы pd реальные номера предприятий не обратив внимания на первичные ключи pch, в связи с чем в таблице pch и добавил поле FK. Ну это не существенно…
*
Наполняем дерево объектами из базы:

// дерево объектов zquery1.Close; zquery1.sql.Clear; with zquery1 do begin if user_pch<>0 then begin // условие ограничивающее пользователя доступом только по предприятию sql.Add('select * from pch where fk= :pP'); Params[0].Value:=user_pch; end; if user_pch=0 then begin // условие разрещающее видеть все предприятия sql.Add('select * from pch '); end; open; end;

Выбор предприятий осуществлен, в продолжение запускаем цикл обрабатывающий данные для наполнения дерева.

while not ZQuery1.Eof do begin // отсюда берем имя ПЧ для главного узла pch_node:= sTreeView1.Items.Add(nil,zquery1.FieldValues['pch']); pch_node.Data:=Pointer(integer(zquery1.FieldValues['fk'])); pch_node.ImageIndex:=2; pch_node.SelectedIndex:=2;

Заполняется имя предприятия (имя ПЧ), устанавливаются параметры отображения иконки и присваивается код для узла.
Узел сформирован. Создаем список цехов для предприятия.

// выбираем ПД для текущего узла zquery2.Close; zquery2.sql.Clear; with zquery2 do begin sql.Add('select * from pd where pkpch= :pPch and rwcode= :pR'); Params[0].Value:=zquery1.FieldValues['fk']; Params[1].Value:=rw; open; end; while not ZQuery2.Eof do begin // отсюда берем имя ПД для узла pd_node:= sTreeView1.Items.AddChild(pch_node,zquery2.FieldValues['pd']); pd_node.Data:=Pointer(integer(zquery2.FieldValues['pk'])); // настройка дерева по условию разграничения доступа пользователей if integer(pd_node.Data)=user_pd then begin // вход в свое ПД pd_node.ImageIndex:=0; pd_node.SelectedIndex:=0; pch_node.ImageIndex:=2; pch_node.SelectedIndex:=2; end else begin if user_pd<>0 then begin // вход в чужое ПД pd_node.ImageIndex:=1; pd_node.SelectedIndex:=1; pd_node.Data:=Pointer(0); pch_node.ImageIndex:=2; pch_node.SelectedIndex:=2; end else begin // вход с уровнем ПЧ или П pd_node.ImageIndex:=0; pd_node.SelectedIndex:=0; pch_node.ImageIndex:=2; pch_node.SelectedIndex:=2; end; end; ZQuery2.Next; end;

На приведенном скрине показано как выглядит полное дерево.
Один из узлов раскрыт для наглядности.
Ниже приведен цикл заполнения цехов вместе с распределением прав доступа к данным связанным с узлом.
Для данных которые недоступны текущему пользователю устанавливаю node.Data:=Pointer(0) и при обращении пользователя — не возвращается никаких данных если ключ равен нулю..
И завершаем начатый цикл перебора предприятий:

Читайте также:  Шпатлевка для дерева технология

ZQuery1.Next;
end;

Осталось только обработать событие смены объекта дерева пользователем:

rocedure TForm1.sTreeView1Change(Sender: TObject; Node: TTreeNode); begin if sTreeView1.Selected.Parent<>nil then begin cur_pch:= integer(sTreeView1.Selected.Parent.Data); сur_pd:= integer(sTreeView1.Selected.Data); end else begin cur_pch:= integer(sTreeView1.Selected.Data); end; end;

С этим можете разобраться самостоятельно.
Здесь происходит получение значений используемых в запросах, в зависимости от размещения объекта в дереве.
А вот так будет выглядеть TreeView, когда пользователю доступен для обработки связанных данных только один из дочерних узлов, при этом не отображаются предприятия к которым пользователь не имеет отношения.
Конечно, для недоступных узлов можно было использовать параметр Cut делающий иконку цвета неактиного элемента(серым), но мне захотелось сделать другой иконкой.

У Вас может быть совсем другая реализация. Это не эталон.
Возможно будут комментарии благодаря которым код станет лучше 🙂

Источник

Оцените статью