TreeView странность.

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: TreeView странность.

Сообщение olegy123 » 02.09.2017 12:54:02

wofs писал(а):Просто в коде процедуру
Код: Выделить всё
FillTree();
буду вызывать через QueueAsyncCall

WTF?
Зачем?
Мултипоточность нужно применять там где это необходимо - иначе решения задачи усложняется в разы.
Вместо правильности кода будете ловить эксепшены в неожиданных местах.
У вас было проблема в утечке памяти. Продолжали работать с зомби классом.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: TreeView странность.

Сообщение wofs » 02.09.2017 13:31:54

olegy123 писал(а):У вас было проблема в утечке памяти. Продолжали работать с зомби классом.

Будьте любезны, объясните - куда она делась (проблема, в смысле)?

Вы говорите много умных слов, спорите друг с другом и каждый пытается донести до ТС свою истину.
Как я понял то, что происходит - я описал выше. Если не прав - поправьте! Если лень - проигнорируйте.

p.s. Я не программист, я железячник, но, иногда, мне нужно некоторое приложение, которое выполняет возложенные на него функции.

Добавлено спустя 5 минут 3 секунды:
vitaly_l писал(а):Понимаете или нет?

Не понимаю. Вот человека, который сказал, что я рублю сук, на котором сижу - понял. А вас не понимаю, увы.

Добавлено спустя 25 минут 49 секунд:
zub писал(а):как только ТС уберет ненужные зависимости из "простого" примера...

А что за зависимости не нравятся? БД? Вы на никсах сидите?
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: TreeView странность.

Сообщение vitaly_l » 02.09.2017 14:11:16

wofs писал(а):Не понимаю.

Попробуйте сделать вот так и у Вас, наконец таки будет настоящая ошибка с утечкой памяти, а не вангинатор, т.к. чистите Вы неправильно. Однако, наличие ошибки - будет означать, что первый этап "создания", вы прошли правильно. см. повторно: http://wiki.freepascal.org/Pointer
Код: Выделить всё

var ptrToInt2 : ^Integer;
begin
// это для одиночного
New(ptrToInt2);
ptrToInt2^ := FieldByName(idNode).asInteger;
node.data := ptrToInt2; // или так @ptrToInt2; - зависит от директивы  Zub - писал выше

// это для цикла
for ... do begin
   New(ptrToInt2);
   ptrToInt2^ := FieldByName(idNode).asInteger;
   Tree1.Items.AddChildObject(Tree1.Items.Item[i], FieldByName(cNodeName).AsString, ptrToInt2 );  // или так @ptrToInt2; зависит от директивы
end;

И вот это, вы уже "вашими" Items[i].Free; Items[i].Data:=nil; - очистить 100% не сможете. И вот эта хрень: QueueAsyncCall - тоже 100% уже не поможет! И возможно даже ваша программа реально рухнет из-за утечки памяти или вообще вылетит BSODa! Но не расстраивайтесь, т.к. - это будет означать что, наконец таки Вы встали на верный путь! А вот как правильно очистить созданное с помощью New(ptrToInt2); посмотрите в инете, т.к. в инете - полно примеров и главное в примерах есть, полноценные объяснения и ссылки на книжки, как и для чего это делают, т.к. это нужно знать и понимать.

И сделайте уже vangamode := off; т.к. ничего вангового в примере ТС нет.

.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: TreeView странность.

Сообщение wofs » 02.09.2017 15:03:29

vitaly_l писал(а):Попробуйте сделать вот так и у Вас, наконец таки будет настоящая ошибка с утечкой памяти, а не вангинатор, т.к. чистите Вы неправильно. Однако, наличие ошибки - будет означать, что первый этап "создания", вы прошли правильно.

Спасибо за максимизацию ошибки - попробую.

Добавлено спустя 5 минут 13 секунд:
vitaly_l писал(а):т.к. это нужно знать и понимать.

Многое нужно знать и понимать, только вот увы, не на все хватает времени и мозгов. Приходится довольствоваться поверхностными знаниями в некоторых областях, от ошибок в которых не погибнут люди. Попробую.

Добавлено спустя 38 минут 59 секунд:
vitaly_l писал(а):Попробуйте сделать вот так и у Вас, наконец таки будет настоящая ошибка с утечкой памяти

Дерево не заполняется. Только корневой узел.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: TreeView странность.

Сообщение vitaly_l » 02.09.2017 15:51:43

wofs писал(а):Дерево не заполняется. Только корневой узел.

покажите код
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: TreeView странность.

Сообщение wofs » 02.09.2017 21:02:48

vitaly_l писал(а):покажите код

Процедура заполнения:
Код: Выделить всё
var
   i:integer;
   ptrToInt2 : ^Integer;
begin
  // Корневой узел (Root), должен быть первым в выборке Query
if not Connect1.Connected then Connect1.Open;
with Query1 do
begin
    Tree1.BeginUpdate;
    Close;
    SQL.Clear;
    SQL.Text:='SELECT * FROM '+TableName+' ORDER BY '+idParent+', '+cNodeName+';'; // запрос на выборку
    Open;
    First;
    Tree1.Items.Clear;

    New(ptrToInt2);
    ptrToInt2^ := FieldByName(idNode).asInteger;

    Tree1.Items.AddObject(nil, FieldByName(cNodeName).AsString, ptrToInt2); // добавляем корневой объект
    Next;
    while not Eof do // перебираем в цикле все записи в Query
    begin
      i := 0;
      while i < Tree1.Items.Count do
        if Tree1.Items.Item[i].Data = Pointer(FieldByName(idParent).asInteger)
          then
        begin
          Form1.Log('i= '+IntToStr(i)+' Node= '+FieldByName(idNode).AsString+' Name= '+FieldByName(cNodeName).AsString);

          New(ptrToInt2);
          ptrToInt2^ := FieldByName(idNode).asInteger;
          Tree1.Items.AddChildObject(Tree1.Items.Item[i], FieldByName(cNodeName).AsString, ptrToInt2);      // добавляем дочерние объекты
          break;
        end
        else
          Inc(i);
      Next;
    end;
  end;
  Tree1.EndUpdate;                                         
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: TreeView странность.

Сообщение vitaly_l » 02.09.2017 21:08:49

А вот так?
Код: Выделить всё
var
   i:integer;
   ptrToInt2 : ^Integer;
begin
  // Корневой узел (Root), должен быть первым в выборке Query
if not Connect1.Connected then Connect1.Open;
with Query1 do
begin
    Tree1.BeginUpdate;
    Close;
    SQL.Clear;
    SQL.Text:='SELECT * FROM '+TableName+' ORDER BY '+idParent+', '+cNodeName+';'; // запрос на выборку
    Open;
    First;
    Tree1.Items.Clear;

    New(ptrToInt2);
    ptrToInt2^ := FieldByName(idNode).asInteger;

    Tree1.Items.AddObject(nil, FieldByName(cNodeName).AsString, @ptrToInt2); // добавляем корневой объект
    Next;
    while not Eof do // перебираем в цикле все записи в Query
    begin
      i := 0;
      while i < Tree1.Items.Count do
        if Tree1.Items.Item[i].Data = Pointer(FieldByName(idParent).asInteger)
          then
        begin
          Form1.Log('i= '+IntToStr(i)+' Node= '+FieldByName(idNode).AsString+' Name= '+FieldByName(cNodeName).AsString);

          New(ptrToInt2);
          ptrToInt2^ := FieldByName(idNode).asInteger;
          Tree1.Items.AddChildObject(Tree1.Items.Item[i], FieldByName(cNodeName).AsString, @ptrToInt2);      // добавляем дочерние объекты
          break;
        end
        else
          Inc(i);
      Next;
    end;
  end;
  Tree1.EndUpdate; 
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: TreeView странность.

Сообщение zub » 02.09.2017 21:16:36

>>А что за зависимости не нравятся? БД? Вы на никсах сидите?
Минимальный пример он на то и минимальный, что содержит только относящееся к ошибке. И уж всяко не должен тянуть пакеты, если проблема не в них.
Цените время форумчан
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: TreeView странность.

Сообщение olegy123 » 02.09.2017 21:23:28

serbod писал(а):wofs, в обработчике изменения узла ты удаляешь изменяемый узел и вообще все узлы. Вот что получается при вызове обработчика:
Код: Выделить всё
      Node:=FEditingItem;
      if (Node<>nil) then begin
        if Assigned(OnEdited) then
          OnEdited(Self,Node,NewText);
        Node.Text:=NewText;  // А Node уже удалили!
      end;

Node.Text:=NewText; // А Node уже удалили!
[Node] удален (Node.Free();), сработал деструктор, удалены все переменные, но он все еще может указывать на участок в памяти где он был (ведь Node не nil, Node.Free не нулит сам Node, для этого есть FreeAndNil(Node);), и вероятно что он может быть рабочим. Ведь Node состояние <неопределенно>. Оно не nil.
Но когда обращаешься к полям/переменным класса (Node.Text:=NewText), то Node.Text = [<неопределенно>].[ <неопределенно>] - указывает в бездну. Отсюда ловишь эксепшен.
Поэтому рекомендуют nil-ить, особенно когда требуется поворотное использование.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: TreeView странность.

Сообщение wofs » 02.09.2017 21:28:02

zub писал(а): И уж всяко не должен тянуть пакеты, если проблема не в них.

Извините, делал штатными компонентами, думал они есть во всех сборках. Переделаю без БД.

Добавлено спустя 5 минут 37 секунд:
vitaly_l писал(а):А вот так?

Аналогично - только корневой узел.
Стоит
Код: Выделить всё
{$mode objfpc}
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: TreeView странность.

Сообщение vitaly_l » 02.09.2017 21:51:02

wofs писал(а):Переделаю без БД

Сделайте минимум, с идентичным заполнением, но только например: 1,2,3,4,5.
И покажите, в своём примере, как вы чистите pointer, с учётом того что говорил Zub. И по возможности постарайтесь изменить свой код так, чтобы не чистить объект/класс из самого себя. Либо, подключайте ещё и QueueAsyncCall
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: TreeView странность.

Сообщение wofs » 02.09.2017 21:55:19

vitaly_l писал(а):Сделайте минимум, с идентичным заполнением, но только например: 1,2,3,4,5.

Сделаю.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: TreeView странность.

Сообщение zub » 02.09.2017 22:16:15

olegy123 писал(а):
wofs писал(а):Просто в коде процедуру
Код: Выделить всё
FillTree();
буду вызывать через QueueAsyncCall

WTF?
Зачем?
Мултипоточность нужно применять там где это необходимо - иначе решения задачи усложняется в разы.
Вместо правильности кода будете ловить эксепшены в неожиданных местах.
У вас было проблема в утечке памяти. Продолжали работать с зомби классом.

Какая тут мультипоточность? это отложенное выполнение процедуры
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: TreeView странность.

Сообщение vitaly_l » 02.09.2017 22:18:44

Вот это неправильно:
Код: Выделить всё
if Tree1.Items.Item[i].Data = Pointer(FieldByName(idParent).asInteger)
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: TreeView странность.

Сообщение wofs » 03.09.2017 00:15:04

Убрал БД.

Изначальный вариант с ошибкой. Пробуем править узел.
https://yadi.sk/d/uo3W0J-g3MYqXY

Вариант, предложенный zub.
https://yadi.sk/d/6ZYVCZQC3MYqaV

Проверил компиляцию Win/Mac - норм.
Аватара пользователя
wofs
постоялец
 
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24

Рейтинг@Mail.ru