Important: Please read the Qt Code of Conduct -

GUI and performance

  • Hi,

    As I explained in other posts, I'm trying to build an application that should be able to show a very long strings, just as shown at the image below.

    I've already tried with some techniques in order to solve this problem: labels for any row, just writing in a scene as a graphicScene item / object, into a table, into a Simple text area...

    But I get always the same low performance. Maybe I should I use openGL with an orthogonal projection (I just need 2D, it's just text) or something like that. There would be some trick to solve it, because I've seen some old applications that are able to load and show this kind of data, why not Qt?

    Some help here?

  • Derive a class from QTextEdit and override scrollContentsBy?

  • Thank you ScottR for your fast reply.

    What should I do in scrollContetsBy?

  • I don' t know, I'm just starting out in Qt.

    However, in straight win32 programming this would be a case for an owner-draw control. There must be some equivalent in Qt.

    Obviously the scrolling in a normal QTextEdit isn't designed for strings that are tens of thousands of characters long. You should reimplement it in a way that gives you the performance you need.

    Maybe you could keep the string in memory and only put into the edit control a small portion of it. Then when the user attempts to scroll past this small amount, replace it with the "next" portion.

    Note that I don't know if this is possible in Qt; it's the way I would do it in native win32. I don't even know if you're working in Windows...

  • In the example shown, you are always drawing the same text. I assume in your real data, you have different texts.

    The fastest way (without graphics hardware support) to paint texts that I know is to:

    • Create a custom QGraphicsItem that does the text drawing in the paint event
    • Set the caching mode to DeviceCoordinateCaching.

    However, in your case there would still be a lot of overhead, for only a part of the text you have is actually visible.

    Therefore, you could further optimize by using the exposedRect in QStyleOptionGraphicsItem (to get this, you need to set the QGraphicsItem::ItemUsesExtendedStyleOption flag).
    In this case, I would turn the DeviceCoordinateCaching of, and do my own caching by drawing first to a pixmap, then painting the pixmap in the paint event. Whenever a different part of the text becomes visible, you would only need to add the part that became newly exposed to the pixmap (with a overlap of some pixels to avoid jittery edges).

  • you could take a look at "Wheel Scroller Example":

    I cannot remember how big is your strings but I modified the example to show 1 mil. strings (* ~ 6 chars each) for each wheel and it still runs fast

  • Hello there,

    Thank you for your replies.

    I'm trying your 2 ways: by setting DeviceCoordinateCaching is still too low. So, I'm trying to draw the text in a pixmap, but if I try to do it using a QPainter new object it's not active. I cannot use the active painter passed as argument in paint method, because is the main painter. Any other way to write text inside a pixmap?

    With your solution, if I've correctly understood, I should reimplement the scroll bar. I'm not sure if it can be applied in this case.

    Many thanks

  • The method to paint into a pixmap is to create a new painter.
    Then you have to call beginPaint() and pass the pointer to the pixmap as an argument. After you are finished, you call endPaint().

    The painter will only add to the pixmap. That means, if you hold the pixmap as a member, you can add those parts of text that just became visible, then just call drawPixmap on the painter you received with the paint() method.

Log in to reply