[Lazarus] How to fix slow screen refresh of TListbox?

Flávio Etrusco flavio.etrusco at gmail.com
Fri Nov 18 22:36:32 CET 2022


Em sex., 11 de nov. de 2022 às 12:29, Bo Berglund via lazarus <
lazarus at lists.lazarus-ide.org> escreveu:
>
> I am using a TListbox component on a form for displaying debug data
arriving
> over a serial line at 115200 baud.
> The data are a set of MQTT telegram texts which arrive in packets of
about 40
> lines each time (once per 10 seconds).
> I add them to the listbox as follows:
>
> procedure THanSimulatorMain.OnRxData(Sender: TObject; const Data: TBytes);
> var
>   len, oldlen: integer;
>   DataTxt: AnsiString;
> begin
>   len := Length(Data); //Incoming packet
>   oldlen := Length(DataBuffer);
>   SetLength(DataBuffer, oldlen + len);
>   Move(Data[0], DataBuffer[oldlen], len);
>   SetLength(DataTxt, Length(DataBuffer));
>   Move(DataBuffer[0], DataTxt[1], Length(DataBuffer));
>   lbxRxData.Items.Text := DataTxt;  //Add the text to the list
>   lbxRxData.ItemIndex := lbxRxData.Items.Count -1; //To make it visible
> end;
>
> DataBuffer is a global TBytes container where the incoming data are
stuffed as
> they arrive (it grows during the session).
> You see that the buffer contains the complete log history from the
start...
>
> I have noticed that after a while the display becomes very sluggish when
data
> arrives and I think that is due to the way the component operates.
>
> Now I wonder if there is some way to do as I did when I worked in Delphi
with
> TListView objects, where I could use the BeginUpdate and EndUpdate calls
to make
> all screen updates wait until it was all put in place.
> This was MUCH faster!
>
> But I can not find a BeginUpdate on the TListBox object, only
BeginUpdateBounds,
> which does not tell me much....
>
> Any suggestions?
>
>
> --
> Bo Berglund
> Developer in Sweden

Hi,

What size is your data? The biggest problem regarding Windows' TListBox
(and TMemo and others) was it used a contiguous buffer for its whole text
and increased capacity by doubling the buffer or something, thus it got
ugly easily; the parsing did seem to have some problems too. Microsoft
alleviated this problem for TMemo at least at some point but I don`t know
about TListBox.
When you set/replace the whole text for a control (ex. using
ListBox1.Items.Text) there`s (usually) no need to use Begin/EndUpdate; if
you're appending a bunch of lines, though, you should use
ListBox1.Items.BeginUpdate.
Do you really need to keep 'DataBuffer' around for other reasons? Otherwise
you could just:

procedure TForm1.OnRxData(Sender: TObject; const Data: TBytes);
var
  buf: TStringList;
  DataTxt: ansistring;
begin
  SetLength(DataTxt, Length(Data));
  Move(Data[0], DataTxt[1], Length(Data));

  buf := TStringList.Create;
  buf.Text := DataTxt;
  SynEdit1.Lines.AddStrings(buf);
  buf.Free;
  SynEdit1.CaretY := SynEdit1.Lines.Count;
end;

Too bad TStrings don`t have a method to add text parsing the linebreaks...
IMHO even a PChar overload with offsets would be deserved.

Best regards,
Flávio
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20221118/44227a4e/attachment.htm>


More information about the lazarus mailing list