TListItem, а Create не Creat'ит

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

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

TListItem, а Create не Creat'ит

Сообщение Sniper » 18.05.2011 21:43:55

Код: Выделить всё
type
TNodeItem = class(TListItem)
public
    parent: TNodeItem;
    i, j: Integer;
end;

var
test:TNodeItem;

test:=TNodeItem.Create();


Что не так-то? Что указывать в скобках?
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Re: TListItem, а Create не Creat'ит

Сообщение Maxizar » 18.05.2011 22:00:05

Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    ListView1: TListView;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

type
TNodeItem = class(TListItem)
public
    parent: TNodeItem;
    i, j: Integer;
end;
var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var T:TNodeItem;
begin
    T:=TNodeItem.Create(ListView1.Items);
    T.Caption:='adf';
    ListView1.Items.AddItem(T);
end;

end.



Поднимитесь по исходнику выше, в данном случае к TListItem = class(TPersistent), это можно сделать так: (Жмем левый CTRL и кликаем ЛКМ по TListItem) Лазарус вас закинет в начало класса TListItem, мы ведь от него наследуемся, так вот значит мы и наследуем его конструктор тобишь смотрим что ему нужно передать.

Видим это:
Код: Выделить всё
constructor Create(AOwner: TListItems);

Тобишь нужно передать TListItems того ListView1 в котором будет этот куст...
Вот если на форму кинуть ListView1. И по клику кнопки сделать выше описанный код, то мы добавим куст с названием 'adf' .. :)
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: TListItem, а Create не Creat'ит

Сообщение Sniper » 18.05.2011 22:08:43

В том то и дело что у меня нет и не будет ListView...
Мне нужен TList и вот такой TListItem.
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Re: TListItem, а Create не Creat'ит

Сообщение Maxizar » 19.05.2011 10:28:56

Код: Выделить всё
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ListView1: TListView;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
type
TNodeItem = class(TListItem)
public
    parent: TNodeItem;
    i, j: Integer;
end;

var
  Form1: TForm1;
  TNodeItemList:TList;
  AOwner: TListItems;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var T:TNodeItem;
    I:Integer;
begin
    if TNodeItemList = nil then
    TNodeItemList:=TList.Create;

    if AOwner = nil then
      AOwner:=TListItems.Create(Nil);

    T:=TNodeItem.Create(AOwner);
    T.Caption:=IntToStr(TNodeItemList.Count);
    //ListView1.Items.AddItem(T);
    TNodeItemList.Add(T);
end;

procedure TForm1.Button2Click(Sender: TObject);
var I:Integer;
    T:TNodeItem;
begin
  if TNodeItemList = nil then exit;

  For I:=0 to TNodeItemList.Count-1 do
    begin
      T:=TNodeItem(TNodeItemList.Items[I]);
      if T <> Nil then
        Memo1.Lines.Add(T.Caption);
    end;
end;

end.



Эксперементы показали, что если ListView нет и если делать так:
Код: Выделить всё
    T:=TNodeItem.Create(Nil);
    T.Caption:='adf';

То будет ошибка... значит при создании TNodeItem обезятельно должен быть указатель на TListItems. Его можно создать отдельно, без него ни одного TNodeItem мы не создадим. В первом варианте я брал TListItems из ListView, во втором варианте, я его создаю сам. Чтобы показать, что TNodeItem создаются по клику на второй кнопке я делаю, перебираю наши созданнные TNodeItem в листе ( TNodeItemList) и запихиваю название куста в Мемо. При этом название каждого куста у нас уникально так как я давал имена так:
Код: Выделить всё
T.Caption:=IntToStr(TNodeItemList.Count);


И еще:
Код: Выделить всё
TNodeItem = class(TListItem)
public
    parent: TNodeItem;
    i, j: Integer;
end; 


Вы создали новый класс, и добавили поле типа класса.. Но конструктор не даете новый... очень опасно, ведь где гарантия что вы не забудите parent: чего нибудь присвоить?... рано или поздно где нибудь ошибетесь. Не легче определить конструктор и в нем Гарантированно сказать что:
Код: Выделить всё
    parent:=Nil;
    i:=0;
   j:=0;

ИМХО: так как то больше уверенности. Или вообще сделать через указатель..
Код: Выделить всё
TNodeItem = class(TListItem)
public
    PToParent: ^TNodeItem;
    i, j: Integer;
end; 
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: TListItem, а Create не Creat'ит

Сообщение Odyssey » 19.05.2011 14:19:47

Sniper писал(а):В том то и дело что у меня нет и не будет ListView...
Мне нужен TList и вот такой TListItem.

Сложно представить, зачем может понадобиться TListItem без TListView. В документации явно указано:
TListItem - the ancestor class for the Items in TCustomListView and TListView
TListItem - класс-предок элементов (Items) TCustomListView и TListView.

Это значит две вещи:
1) он не имеет к TList никакого отношения;
2) он не предназначен для работы без ListView, и пытаться от него наследоваться чтобы выполнить какую-то свою задачу без ListView - это искать проблем на ровном месте.
Я бы сделал так:
Код: Выделить всё
TNodeItem = class
public
    parent: TNodeItem;
    i, j: Integer;
end;

Если нужны какие-то конкретные функции или методы, которые есть у TListItem, их проще реализовать в своём классе независимо от TListItem.

Плюс, в качестве контейнера вместо TList можно использовать TFPObjectList из модуля Contnrs. В отличие от TList он хранит TObject'ы а не Pointer'ы, и автоматически освобождает их при своём освобождении.
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24


Вернуться в Lazarus

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

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

Рейтинг@Mail.ru