Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.05.07;
Скачать: [xml.tar.bz2];

Вниз

Работа с TreeView, как "нарисовать" дерево   Найти похожие ветки 

 
STK ©   (2006-04-10 21:34) [0]

Проблема такая, что я думаю многие кто сталкивался.

Есть ini файлы в которых прописаны некоторые данные. И имеется связьмежду ними. Лучше наверно показать.
Строки из ini файла:

[первый]
количество связей = 2
связь №1 = второй
связь №2 = четвёртый
связь выше = нуль
[второй]
количество связей = 1
связь №1 = третий
связь выше = первый
[третий]
количество связей = 0
связь выше = второй
[четвёртый]
количество связей = 2
связь №1 = пятый
связь №2 = шестой
связь выше = первый

Т.е. у [номер] есть запись сколько у него связей, и номера с тем с кем он связан. У [номера] есть только одна связь сверху, и может быть несколько с тем кто ниже.

Вот эти связи необходимо нарисовать в TreeView.

Кто может помогите пожалуйста. Заранее всем спасибо.


 
STK ©   (2006-04-10 21:40) [1]

Если что-то непонятно, я распишу.


 
Мефисто   (2006-04-10 22:16) [2]

\Delphi\Demos\CustomDraw


 
STK ©   (2006-04-10 22:55) [3]


> Мефисто   (10.04.06 22:16) [2]
> \Delphi\Demos\CustomDraw

Нет это не-то мне надо формировать дерево, а там красят и всё такое. Так и я могу. Мне нужен алгоритм. Чтоб он с самого первого работал и до последнего. Иерархию строил. Чтоб каждая запись одна под другой. Наверняка такая тема у кого-нить всплывала. А алгоритм который я придумал боюсь  заставит зависнуть ПК при количестве связей более 1000, а у меня их с 5000 если небольше.


 
Мефисто   (2006-04-10 23:09) [4]

// не будет заморачиваться с отрисовкой на время создания веток
 TreeView1.Items.BeginUpdate;

 TreeView1.Items.Add - подробнее по F1
 строй ветки как хочешь...
 ...

 TreeView1.Items.EndUpdate;


 
STK ©   (2006-04-10 23:16) [5]


> Мефисто   (10.04.06 23:09) [4]
> // не будет заморачиваться с отрисовкой на время создания
> веток
>  TreeView1.Items.BeginUpdate;
>
>  TreeView1.Items.Add - подробнее по F1
>  строй ветки как хочешь...
>  ...
>
>  TreeView1.Items.EndUpdate;

Ты не понял. Мне надо алгоритм, чтоб он их из файлов брал и вставлял в TreeView. Т.е. сначала самый первый, затем все вторые (ну как параметр Level), затем третьи, и т.д. но так чтоб каждый под своим был. Это дерево может иметь "не постоянный рисунок" где-то закончиться на 5 уровне, а где-то на 100 уровне.   МНЕ НУЖЕН Алгоритм. Вот ивсё. А добавлять записи-стоки-"листочки дерева" я умею.

Может чего придумаеш. Но мой алгоритм очень плох.


 
Мефисто   (2006-04-10 23:20) [6]

Тогда Т.З. шире раскрой. А то по первому посту не очень възжаю чего надо. Ини файл сразу в сторону т.к. для алгоритма он не важен. Типа, чего за записиси и по каким признакам их нужно сгруппировать...


 
STK ©   (2006-04-10 23:34) [7]

Одним словом покажу суть: представь
Ты знаеш что такое сетевой маркетинг? Как там иерархия строится? Так вот это полный прототип. Есть "человек" который знает кто у него главный-это с одной стороны, и есть его дистребютеры(чёрт знает как писать). Он знает только их имена и их количество.
Так вот дерево надо строить с первого. потом прикрепитьк нему вторых. затем каждому второму надо прикрепить их третьих. чтоб там не получилось что он принадлежал одному а оказался в связи с другим.

Ну незнай как там Тех Задан получилось, но с сетевым маркетингом очень похож. Если не понятно могу вообще на пальцах объяснить, но это тяжело.


 
Мефисто   (2006-04-10 23:46) [8]

Если такого рода связи,

http://slil.ru/22673768

то вчем проблема? Ветки ты говоишь строить умеешь. А судя по ини файлу, ты ведь инфу как-то по признакам групперуешь.  Что мешает сделать тоже самое но с ветками? До меня пока не доходит :)


 
STK ©   (2006-04-10 23:56) [9]

Вай, Вай, Вай.

Всё это понятно. Может я чего не знаю о TreeView? Из-за этого у меня не чё и не прёт.

Но с этим всё понятно(с рисунком). Мне надо чтоб после того как я добавил последнего участника одного уровня. Начать добавлять участника следующего уровня. Но как запомнить с кого начать, и кем дальше продолжить. если на одном уровне может быть около 1000 записей. Сам посмотри на рисунке на 3 уровне сколько. а на 30 уровне-очень много.

А cделать
TreeView.items.add(); я могу . - но как тут вставить именно ту ветвь в которую надо вставить я не знаю. Нужно чтоб оптимально и быстро.


 
Мефисто   (2006-04-11 00:10) [10]

Посмотри по справке внимательно, что возвращает TreeView.items.add.
Правильно, ссылку на созданную вновь ветку дерева.
Про рекурсивный вызов процедур/функций слышал? Это в твоем случае может очень почочь. И глянь еще раз справку, может поможет. А с кодом может завтра если чего накидаю и то ближе к полуночи. Но я думаю ты и сам справишся :)


 
PZ   (2006-04-11 09:00) [11]

Посмотрите, может поможет:
http://www.delphikingdom.com/asp/viewitem.asp?catalogID=488


 
STK ©   (2006-04-11 10:48) [12]


> Мефисто   (11.04.06 00:10) [10]

Про рекурсию слыхал. Мой алгоритм просто в цикле сделан, может из-за этого. Но не думаю.

Ещё это может помешать закрытию файлов ini (помоему может). Но попробую, посмотрю что получится.

> PZ   (11.04.06 09:00) [11]
> Посмотрите, может поможет:
> http://www.delphikingdom.com/asp/viewitem.asp?catalogID=488

Посмотрю, вроде оно, ведь они тоже строят исходя из связей, Но ...
Спасибо посмотрю.


 
STK ©   (2006-04-12 00:02) [13]

Нечего не понятно, если честно. Но явного построения нет, этонаверняка.
Может кто чего другого предложит, очень нужно.


 
ЮЮ ©   (2006-04-12 11:47) [14]

Держи, я сегодня добрый.
Однако здесь нет проверки на вложенные зацикливания,типа

[первый]
связь выше = второй
[второй]
связь выше = первый

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ComCtrls;

type
 TForm1 = class(TForm)
   TreeView1: TTreeView;
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

uses IniFiles;

{$R *.dfm}

procedure FillTreeFromIni(TreeView: TTreeView; ini: TMemIniFile);
var
 sl: TStringList;
 i: integer;
 parent: string;
 parentIdx: integer;
 children, root: TList;

 procedure FillNode(Root: TTreeNode; Children: TList);
 var
   i, idx: integer;
   node: TTreeNode;
   list: TList;
 begin
   for i := 0 to Children.Count - 1 do begin
     idx := Integer(Children[i]);
     node := TreeView.Items.AddChild(Root, sl[idx]);
     list := TList(sl.Objects[idx]);
     if list <> nil then begin
       FillNode(node, list)
     end;
   end;
 end;

begin
 sl := TStringList.Create;
 root := TList.Create;
 try
   ini.ReadSections(sl);
   for i := 0 to sl.Count - 1 do sl.Objects[i] := nil;
     //sl.Object заполнено "строками" секции, а мы намерены
     //испльзовать для списка детей

   // создаем виртуальное дерево
   for i := 0 to sl.Count - 1 do begin
     parent := ini.ReadString(sl[i], "связь выше", "");
     if parent = "нуль" then
       root.Add(TObject(i))
     else begin
       parentIdx := sl.IndexOf(parent);
       if parentIdx < 0 then
         //связь выше имеет недопустимое значение
       else if parentIdx = i then
         //ссылка на самого себя
       else begin
         if sl.Objects[parentIdx] = nil then
            sl.Objects[parentIdx] := TList.Create;
         children := TList(sl.Objects[parentIdx]);
         children.Add(TObject(i))
       end;
     end;
   end;

   // заполняем TreeView
   if not Assigned(TreeView) then Exit;

   TreeView.Items.BeginUpdate;
   try
     TreeView.Items.Clear;
     TreeView.Items.Add(nil, "нуль");
     FillNode(TreeView.Items[0], root);
   finally
     TreeView.Items.EndUpdate;
   end;
 finally
   for i := 0 to sl.Count - 1 do
     sl.Objects[i].Free;
    sl.Free;
    root.Free;
 end;
end;

procedure FillTreeFromFile(TreeView: TTreeView; FileName: TFileName);
// ТMenIniFile и TStringList не имеют ограничений по размеру,
// в отличии от TIniFile
var
 sl: TStringList;
 ini: TMemIniFile;
begin
 sl := TStringList.Create;
 ini := TMemIniFile.Create("tree.ini");
 try
   sl.LoadFromFile(FileName);
   ini.GetStrings(sl);
   FillTreeFromIni(TreeView, ini);
 finally
   sl.Free;
   ini.Free;
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FillTreeFromFile(TreeView1, ExtractFilePath(ParamStr(0)) + "tree.ini");
end;

end.


 
STK ©   (2006-04-12 22:16) [15]


> ЮЮ ©   (12.04.06 11:47) [14]
> Держи, я сегодня добрый.
> Однако здесь нет проверки на вложенные зацикливания,типа
>
>
> [первый]
> связь выше = второй
> [второй]
> связь выше = первый

Спасибо большое. Но у меня и нет подобного.

Как я по первому взгляду пойму - это дерево строится сразу и полностью?
или как?
И если можно чуть больше коментариев, правда это уже наглость, но я чувствую что ты и сегодня добрый будеш, но это на твоё усмотрение.

Ещё раз спасибо.


 
STK ©   (2006-04-12 22:56) [16]


> ЮЮ ©   (12.04.06 11:47) [14]
> Держи, я сегодня добрый.
> Однако здесь нет проверки на вложенные зацикливания,типа
>

Всё работает как часы. Это очень круто. Спасибо что ты мне помог. Я уже протестировал код. Работает. Поповоду коментариев - ненадо. Походу пошагового я разобрался более или менее. Правда вот есть такая тема, что если файлов более чем один. Буду конечно сам разбираться, но...

И если можно: что это затип TMemIniFile - некогда не слыхал и не видал. Какой унит в усес подключать?
Что-то Архангельский(моя настольная книга)про это умалчивает. Только не надо про книги. Я на них уже ~1500р. потратил и нового покупать не хочу, ПОКА. Если только Пачеко и Тейксера.

И чё-то у меня пробел не фурычит, так-что не обессутьте за отсутствие пробелов.


 
STK ©   (2006-04-12 23:15) [17]

Что-то в инете копаю, а инфы толком нет.

Ещё что-то дельфийская помощь умерла: показывает что не может найти d7.hlp, при этом показывает  весь путь без слешей "\". Хрень какая-то. Наверно придётся ручками исправлять.

Может кто подскажет ли ссылочку покажет?

Заранее же спасибо.


 
STK ©   (2006-04-12 23:21) [18]

Блин куда я смотрю: типто называется ТMenIniFile а я ищу ТMemIniFile. Всё пора спать. В Уфе уже 1:21. всем спокойного времени суток.


 
STK ©   (2006-04-12 23:25) [19]


> procedure FillTreeFromFile(TreeView: TTreeView; FileName:
>  TFileName);
> // ТMenIniFile и TStringList не имеют ограничений по размеру,
>
> // в отличии от TIniFile
> var

Я отсюда взял ТMenIniFileа оказывается точно ТMemIniFile. Это доказывает: людям свойственно ошибаться.

Всё проблема решена. Но мне надо использовать несколько файлов ini - а этозначитнадодумать дальше.


 
STK ©   (2006-04-20 22:05) [20]


>  sl := TStringList.Create;
>   ini.ReadSections(sl);


А можно ли здесь зделать так:

ini - ini файл

sl := TStringList.Create;
for i:=0 to N do
iniN.ReadSections(sl);


т.е. добавлять к sl ещё строки из других инишников.

Или это делается другимиметодами?



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2006.05.07;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.009 c
2-1145269028
Leshas
2006-04-17 14:17
2006.05.07
Математическое приложение - разбор формулы


15-1145210601
Гарри Поттер
2006-04-16 22:03
2006.05.07
С edlm2.exe кто знаком?


15-1144781049
palva
2006-04-11 22:44
2006.05.07
Цифровая крепость Дэна Брауна


1-1143741211
Mortem
2006-03-30 21:53
2006.05.07
Crt под Delphi


15-1144668041
Ega23
2006-04-10 15:20
2006.05.07
Итак, завтра с 18:40 буду возле Грибоедова





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский