[Решено] Посоветуйте компонент ListView но с форматированием

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

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

AlexDanilov
новенький
Сообщения: 17
Зарегистрирован: 24.10.2016 14:11:46
Откуда: Kiev

[Решено] Посоветуйте компонент ListView но с форматированием

Сообщение AlexDanilov »

Добрый вечер, коллеги.

Пожалуйста, посоветуйте компонент табличного представления, в котором можно:
1. Управлять высотой или отступами в ячейках
2. Задавать шрифт каждой ячейке
3. Выводить многострочное содержание

Во вложении пример, как я хочу, чтобы таблица выглядела.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Последний раз редактировалось AlexDanilov 01.11.2016 17:14:54, всего редактировалось 1 раз.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

TListView с OwnerDraw?
Хотя емнип ownerdraw там глючный был
Аватара пользователя
DYUMON
постоялец
Сообщения: 234
Зарегистрирован: 11.03.2009 12:32:54
Контактная информация:

Сообщение DYUMON »

ручками придется рисовать походу, я подобное видел только у tms advcardlist
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3071
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

Такое в полной мере реализовано только в Delphi Firemonkey. Отчасти - в CodeTyphon ORCA. В стандартном лазаре ничего похожего не имеется, одно УГ.
Alex2013
долгожитель
Сообщения: 3232
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Для того что ты хочешь сделать действительно готовых компонентов почти нет
Я бы на твоем месте просто динамический на создавал однотипных панелек (с Algin:=alTop) и прикрутил скролбар и реакцию на конопки прямо в форме . Тупо зато никаких проблем "с рисованием по точкам " и кривым ownerdraw. :idea:

Вот похожий кусок кода (Только координаты читает из ини-файла а у тебя просто таблица и с Algin:=alTop все будет еще проще )

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

procedure TWQ_MForm.FormCreate(Sender: TObject);
  var Ini:TIniFile ;
      I,BC:Longint;
      B1: TButton;
      PL: TPanel;
      S:TShape;
      ST:String;
      PRO:TProcess;
      Im:TImage;

      BX,BY,BW,BH,BI,BF :Longint;
begin
   Ini:=TInifile.Create('WinQwest.ini');

 // Настройка и загрузка главного меню

 self.Caption:=AnsiToUTF8(ini.ReadString('WinQwest','Caption','WinQwest' )) ;

   //===Размеры=Окна=========================================
   self.Top   := StrToInt(ini.ReadString('WinQwest','X','5' ));
   self.Left  := StrToInt(ini.ReadString('WinQwest','Y','2' ));
   self.Width := StrToInt(ini.ReadString('WinQwest','W','35' ));
   self.Height:= StrToInt(ini.ReadString('WinQwest','H','250' ));
   //-Размеры-и-позитция-кнопок-меню------------------------

   BX:=StrToInt(ini.ReadString('WinQwest','BX','23' ));
   BY:=StrToInt(ini.ReadString('WinQwest','BY','11' ));
   BW:=StrToInt(ini.ReadString('WinQwest','BW','283' ));
   BH:=StrToInt(ini.ReadString('WinQwest','BH','31' ));
   //----Интервал--между-кнопками-------------------------
   BI:=StrToInt(ini.ReadString('WinQwest','BI','45' ));
   //----Размер Шрифта------------------------------------
   BF:=StrToInt(ini.ReadString('WinQwest','BF','21' ));


   //----------------------------------------------------------
   self.Icon.LoadFromFile(ini.ReadString('WinQwest','ICO','WinQ.ico' ));
   ATop := StrToInt(ini.ReadString('WinQwest','ATOP','0' ))=1;
   If aTop Then FormStyle:=fsStayOnTop;
 //============================================================
   self.Color:=StrToInt(ini.ReadString('MainMenu','ColorMenu','5739300' ));
   BC:=StrToInt(ini.ReadString('MainMenu','CountMenuItem','0' ));
    // -- Цвет кнопки -------------------
   ColorBatton:=StrToInt(ini.ReadString('MainMenu','ColorBatton','$F0FFFF' ));
   ColorABatton:=StrToInt(ini.ReadString('MainMenu','ColorABatton','$FFFF' ));
   //----------------------------------------------------------

// -----------------------создание панелек  в цикле ------------------------
   IF BC > 0 then for I:=1 to bc do
   begin
   PL:= TPanel.Create(self);
     PL.Caption:=AnsiToUTF8(ini.ReadString('MainMenu','MenuItem_'+
                 IntToStr(i)+'_Text',''));
     PL.Hint:= AnsiToUTF8(ini.ReadString('MainMenu','MenuItem_'+
                 IntToStr(i)+'_Run',''));
    PL.Left := BX ;
    PL.Height := BH;
    PL.Top := BY +BI*(I-1);
    PL.Width := BW ;
      if i=1 then  PL.Color :=  ColorABatton else
             PL.Color :=ColorBatton ;
    PL.Font.Height := bf;
    PL.Font.Name := 'Times New Roman' ;
    PL.OnClick:=@Button1Click;
    self.InsertControl(PL)
   end;
// -----------------------------------------------------------------
   ini.free;
end;
Последний раз редактировалось Alex2013 26.10.2016 13:02:27, всего редактировалось 1 раз.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>ручками придется рисовать походу, я подобное видел только у tms advcardlist
Внутрености итемов всяко рисовать ручками

>>Такое в полной мере реализовано только в Delphi Firemonkey. Отчасти - в CodeTyphon ORCA. В стандартном лазаре ничего похожего не имеется, одно УГ.
Предлагаете ставить и юзать мешок фантиков? УГ когда отдельный компонент на каждый случай, и всё это разнородное и в одном проекте

>>Для того что ты хочешь сделать действительно готовых компонентов почти нет
Тяжело найти компонент "типа ListView" более чем сам ListView))
>>Я бы на твоем месте просто динамический на создавал однотипных панелек (с Algin:=alTop) и прикрутил скролбар и реакцию на конопки прямо в форме .
и поймал тормоза на тысяче итемов? кроме того что разместить одно под другим нужно сделать еще очень много "лишнего"
>>Тупо зато никаких проблем "с рисованием по точкам " и кривым ownerdraw. :idea:
Чем рисование на панельке лучше чем рисование на чемто другом?
А проблемы с овнердравом есть ровно до того момента когда он комуто понадобится и этот ктото оформит багрепорт и приложит к нему пример с воспроизведением
Alex2013
долгожитель
Сообщения: 3232
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Чем рисование на панельке лучше чем рисование на чемто другом?

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

Единственный недостаток "ручного" метода нужно самостоятельно обрабатывать команды на скролиинг но это явно ерунда если в программе только одна "нестандартная таблица "
Последний раз редактировалось Alex2013 26.10.2016 13:19:21, всего редактировалось 1 раз.
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Тем что можно юзать центровку прочий сервис стандартных компонент не вникая в "тонкую механику" а в общем случае даже в координаты . Важно не на чем "рисовать" а как "рисовать"
То про что ты говоришь называется TFlowPanel, но к топику оно не относится никак((
Важно что рисовать всеравно придется, а что выступает в качестве "подложки" - панелька, канвас итема ListView`а - разницы рисующему нет абсолютно никакой

Добавлено спустя 3 минуты 13 секунд:
>>Тем что можно юзать центровку и прочий сервис стандартных компонен
Ты понимаешь каким слоем жира ты обмазываешь элементарную нужду? вместо одного вызова TextOut ты городишь несколько контролов с хендлами...
Alex2013
долгожитель
Сообщения: 3232
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Ты понимаешь каким слоем жира ты обмазываешь элементарную нужду? вместо одного вызова TextOut ты городишь несколько контролов с хендлами...

Угу угу "вместо одного вызова TextOut"... и за штифтом следи, и рамочку и фон рисуй, и буковки центруй, и разные неожиданные баги с РИСОВАНИЕМ получай...

Нет, пойми меня правильно, я OwnerDraw применяю с удовольствием ... но только там где без него не обойтись!
( в случаях вроде рисования цветного MainMenu )... и где перекрывать логику управления гораздо сложнее чем изменить прорисовку одного элемента.

ты городишь несколько контролов с хендлами...

Звучит от как страшно .... Ууууу..... :roll: :wink:
Но это со стороны системы "ужос разбирает " а программист в простейшем случае пишет в цикл одну заведомо работающую строчку:

PL:= TPanel.Create(self); PL.Caption:=MyStrList[ i ]; PL.Height := 30; Algin:=alTop; InsertControl(PL);

"Взул и забул!" :mrgreen:

AlexDanilov привел чуть более сложную картинку но ничего не мешает вставить в панельку несколько TLabel ... :idea:
(И как вариант занести в список те что хранят изменяемое при скорлинге значение, хотя можно и просто заменить как-то так OP:=Controls[i]; Controls[i] :=MyNewPanelCreate(i,data1,data2...); Op.free; ).
Чуть сложнее ?
Да, но "рисование" мало того что может быть не мене сложно так еще и может быть не очень надежно .

Добавлено спустя 2 часа 18 минут 20 секунд:
Вот еще кусок кода (выводит иконки в три ряда и тут даже скроллинг автоматом работает если на скролбох вставить надо будет его кстати вернуть )...

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

  
For I:=0 to tc-1 DO Begin
   if (i+1) = k    then begin
     PN:=TPanel.Create(Self);     CurToolsList.Add(pn);  K:=CurToolsList.Count-1;

//Вывод иконок в три ряда тут сделан топорно  можно сделать гораздо красивее
// просто добавить вставку панели ряда с Algin:=alTop;
///а сами иконки вставить по   Algin:=alRight;
     pn.Top:=Panel3.Height+Panel13.Height*2*(k div 3)+3;
     pn.Left:=40*(k mod 3);    Pn.Width:=40;    pn.Height:=Panel13.Height*2;
//------------------------------------- END "Topor"-------------------------
     pn.Hint:=ARTools[i].Hint;
     pn.ShowHint:=True;
     pn.HelpContext:=i;//! Все в порядке индекс записывается "железно"
     Pn.OnClick:=@PanelClick; //Если иконки нет то на что-то нажимать все равно нужно
     Pn.OnPaint:=@ToolsPanelPaint;// Тут просто выделение активного элемента задумано ... 

    if FileExists(SCR_DIR+ARTools[i].ICO) then begin
       Img:=TImage.Create(pn);      img.Align:=alClient;   
       img.OnClick:=@ImageClick;
       Img.Picture.LoadFromFile(SCR_DIR+ARTools[i].ICO );
       pn.InsertControl(img);     img.Stretch:=true;
     end  else pn.Caption:=ARTools[i].Name; ;
     Panel1.InsertControl(pn);
   end
  end;

Суть в том что очень часто если программе что-то рисуется "одноразово" то можно не заворачиваясь с рисованием делать динамическую форму из стандартных компонентов, а если нужно одно решение для нескольких разных блоков то можно затратить силы на отладку изменения прорисовки делая свой отдельный "не стандартный" компонент.
OwnerDraw промежуточное решение удобен тем что позволяет менять вид в RunTime не меняя удобства создания форм .
Последний раз редактировалось Alex2013 26.10.2016 16:37:28, всего редактировалось 1 раз.
AlexDanilov
новенький
Сообщения: 17
Зарегистрирован: 24.10.2016 14:11:46
Откуда: Kiev

Сообщение AlexDanilov »

Спасибо, попробую.

Я вот читаю, что VirtualTreeview http://wiki.freepascal.org/VirtualTreeview может мне помочь.

Есть еще вот такой компонент, но он у меня не скомпилировался. http://avemey.com/zcolorstringgrid/zcol ... hp?lang=ru
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Нет, пойми меня правильно, я OwnerDraw применяю с удовольствием ... но только там где без него не обойтись!
Я видел. кислота и кривое определение ширины)) Но там ведь ты тоже мог поставить панельки. Двойные стандарты))

>>"Взул и забул!" :mrgreen:
Я уже понял что через голову до тебя недоходит)) Давай через руки?
Ты делаешь минимальный такой контрол "панельками" я овнердравом в TListView.
Должно быть доведено до состояния легкого использования на чужой стороне: создал контрол и добавил итемы.
Функционал: добавлениеудаление итемов, выделение мышкой, мультиселект, подсветка элемента под мышкой... так и быть, управление с клавиатуры тебе простим))
Потом сравниваем объем кода (у меня думаю получится 1 метод, строк на 30 - рисование итема, + минимальная обвязка массива хранящего дополнительную инфу итемов типа форматирования), и проводим стресстестик какойнить - например на выживание и качество жизни после добавления ~10000 итемов,
С меня заодно багрепорты на овнердрав, если оно еще неисправлено

Добавлено спустя 26 минут 28 секунд:
>>Да, но "рисование" мало того что может быть не мене сложно так еще и может быть не очень надежно .
Какие там могут быть проблемы?
Аватара пользователя
Лекс Айрин
долгожитель
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград
Контактная информация:

Сообщение Лекс Айрин »

AlexDanilov писал(а):Я вот читаю, что VirtualTreeview...

дерево и список понятия разные.
Alex2013
долгожитель
Сообщения: 3232
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

>>Да, но "рисование" мало того что может быть не мене сложно так еще и может быть не очень надежно .
Какие там могут быть проблемы?

Рисование по умолчанию более низкий уровень . Если все идеально проблем не будет... Но я неоднократно сталкивался с не вполне понятными фокусами поведения системы при попытках делать что-то не стандартным образом .
Например некие последовательности прямого рисования на экранном конвасе не срабатываю совсем :shock: ... а в другом порядке или при буферизации все нормально ... В стандартных компонентах все отлажено и думать о заморочках GDI и GUI нужды нет .
zub писал(а):>>"Взул и забул!"
Я уже понял что через голову до тебя недоходит)) Давай через руки?

Хорошо попробую .... :wink:
zub
долгожитель
Сообщения: 2890
Зарегистрирован: 14.11.2005 22:51:26
Контактная информация:

Сообщение zub »

>>Например некие последовательности
Надо было разобраться, а не списывать на ненадежность. Не всё работает так как ты ожидаешь, но всегда можно вникнуть
Alex2013
долгожитель
Сообщения: 3232
Зарегистрирован: 03.04.2013 11:59:44

Сообщение Alex2013 »

Стебу то ... а возни на десять минут ....


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

Function  TF1.NewItemSList(Stol,Zall,Cena,Sost:String; Sel:Boolean):TPanel;
var
  PL,PL1,PL2:TPanel;
begin
PL:=TPanel.Create(f1);pl.Align:=alTop;  PL.Height:=82;
if sel then pl.Color:=clRed;
PL.Caption:=Cena;
PL1:=TPanel.Create(pl); PL1.Width:=80; pl1.Align:=alLeft;
  PL.InsertControl(PL1);
     PL2:=TPanel.Create(pl1); PL2.Height:=40; pl2.Align:=alTop;
     PL2.Caption:=Zall;
      PL1.InsertControl(PL2);
     PL2:=TPanel.Create(pl1); PL2.Height:=40; pl2.Align:=alTop;
     PL2.Caption:=Stol;
      PL1.InsertControl(PL2);
 PL1:=TPanel.Create(pl); PL1.Width:=60; pl1.Align:=alRight; pl1.Font.Color:=clGreen;
 PL1.Caption:=Sost;
  PL.InsertControl(PL1);
pl.OnClick:=@Panel1Click;
Result:=PL;
end;

Разумеется полный скроллинг я писать не стал ... Но вывести 10 элементов с любой позиции в списке это настолько просто, что даже лень показывать ...
А демка такая .

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

procedure TF1.FormCreate(Sender: TObject);
var IT:TPanel;
    I:Integer;
begin
SuperList:=Tlist.Create;
for i:=100 downto  1 do begin
IT:= NewItemSList( 'Стол '+IntToStr(i),'Малый зал','300$','Закрыт',false);
 SuperList.Add(IT);
 ScrollBox1.InsertControl(iT);
end;

end;
procedure TF1.Panel1Click(Sender: TObject);
begin
 If TPanel(Sender).Color<>ClRed Then TPanel(Sender).Color:=clRed else  TPanel(Sender).Color:=Color;
end;
Последний раз редактировалось Alex2013 07.09.2022 12:50:32, всего редактировалось 2 раза.
Ответить