2 Stimmen

Wie kann ich eine große Menge an Rich Content (Bilder, Formatierung) schnell an ein Steuerelement anhängen, ohne Tonnen von CPU zu verwenden?

Ich verwende wxWidgets und Visual C++, um eine Funktionalität zu schaffen, die der Verwendung von Unix "tail -f" mit reichhaltiger Formatierung (Farben, Schriftarten, Bilder) in einer GUI ähnelt. Ich ziele sowohl auf wxMSW als auch auf wxMAC ab.

Die offensichtliche Antwort ist die Verwendung von wxTextCtrl mit wxTE_RICH, mit Aufrufen von wxTextCtrl::SetDefaultStyle() und wxTextCtrl::WriteText().

Auf meiner 3-GHz-Workstation, die im Freigabemodus kompiliert wurde, bin ich jedoch nicht in der Lage, ein Protokoll zu verfolgen, das im Durchschnitt um 1 ms pro Zeile wächst und schließlich zurückfällt. Für jede Zeile, ich bin anfallenden:

  1. Zwei Aufrufe von SetDefaultStyle()
  2. Zwei Aufrufe zwei WriteText()
  3. Ein Aufruf zum Einfrieren() und Auftauen() des Widgets

Wenn ich dies ausführe, geht meine CPU auf einem Kern mit wxMSW auf 100 %, nachdem etwa 20.000 Zeilen gefüllt wurden. Das Programm ist sichtbar langsamer, sobald es einen bestimmten Schwellenwert erreicht und fällt weiter zurück.

Ich bin offen für die Verwendung anderer Steuerelemente (wxListCtrl, wxRichTextCtrl, usw.).

1voto

Mecki Punkte 113876

Haben Sie erwogen, die Anzahl der Zeilen in der Ansicht zu begrenzen? Als wir ein ähnliches Problem hatten, haben wir einfach sichergestellt, dass nie mehr als 10.000 Zeilen in der Ansicht sind. Wenn unten mehr Zeilen hinzukommen, entfernen wir die Zeilen oben. Dies geschah nicht mit WxWidgets, sondern mit einer nativen Cocoa UI auf dem Mac, aber das Problem ist dasselbe. Wenn eine gestylte Textansicht (mit Farben, Formatierung und schönem Druck) zu groß wird, wird das Anhängen weiterer Daten am unteren Rand ziemlich langsam.

0voto

bobwienholt Punkte 17040

Es scheint, dass die von Ihnen verwendete Steuerung einfach nicht für die Datenmenge ausgelegt ist, die Sie ihr zuführen. Ich würde erwägen, eine benutzerdefinierte Steuerung zu bauen. Hier sind einige Dinge, die Sie in Betracht ziehen könnten:

  1. Wenn eine neue Zeile hinzukommt, brauchen Sie die vorherigen Zeilen nicht neu zu rendern... sie ändern sich nicht und das Layout wird durch die neuen Daten nicht verändert.
  2. Versuchen Sie, jeweils nur den sichtbaren Teil und einige Bildschirme des Rückblicks im Gedächtnis zu behalten. Das würde es ein wenig leichter machen... aber Sie müssen Ihr eigenes Scroll-Management machen, wenn Sie wollen, dass der Benutzer in der Lage ist, weiter zurückzublättern als Ihr Look-back und alles nahtlos erscheinen zu lassen.
  3. Aktualisieren Sie nicht unbedingt eine Zeile nach der anderen. Wenn es neue Daten gibt, nehmen Sie sie alle auf und aktualisieren Sie sie. Wenn Sie sehr schnell 10 Zeilen erhalten und den Bildschirm auf einmal aktualisieren, können Sie sich einen Teil des Aufwands ersparen, der bei einer zeilenweisen Aktualisierung anfällt.

Ich hoffe, das hilft.

0voto

Michael Labbé Punkte 11449

Abgeleitet von wxVListBox. Aus der Doku:

wxVListBox ist ein listbox-ähnliches Steuerelement mit den folgenden zwei Hauptunterschieden zu einer regulären Listbox: es kann eine beliebig große Anzahl von Elementen haben, weil es sie nicht selbst speichert, sondern OnDrawItem()-Callback verwendet, um sie zu zeichnen (also ist es eine virtuelle Listbox) und seine Elemente können eine variable Höhe haben, die durch OnMeasureItem() bestimmt wird (also ist es auch eine Listbox mit den Zeilen der variablen Höhe).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X