Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

qt - setText outside of paint events not ok?

Tags:

c++

qt

Under Qt 4.7.1, Qt Creator 2.1.0, OS X 10.6.8:

I have a QLabel in the mainwindow ui, which uses Courier New / 13, with room for four lines of text.

I create four lines of text, considerably shorter than the label is horizontally, of the general format:

"my text\r\n"

I filter the text before sending it along. The only characters in the cstring will be 0x0D, 0x0A, 0x20 (space) and from there up to lower case z (0x7A') and of course the terminating zero. No other control characters - if they are received from the source, I replace them with '*'

I send the four lines of text to the QLabel as a single zero-terminated cstring via setText()

I sometimes do this at a fairly high rate, several times a second at least -- this is RDBS data from an FM station so it changes in real time:

qDebug() << rbl;                    // data keeps coming to console
ui->fourLineLabel->setText(rbl);    // add this, display soon stops updating

This works. For a while. Then the display stops updating. This is the area at issue:

4-line QLabel
(source: fyngyrz.com)

If I leave everything else in, but take out the setText(), the problem does not occur.

I know that for some things, Qt wants painting to be done within a paint event. Is this also true of a setText() ?

Reading the docs on qt widgets, it says that widgets do their own painting within their own paint event... but the behavior here is very similar to the kind of malfappery that goes on when one actually tries to use a painter outside of a paint event. And it's definitely related to that setText(), so... mumble.

As I write this, the application has been running for hours without any display lockup, outputting the same text to the console via qDebug(). It takes about 5 minutes for the problem to occur if I uncomment the setText(). It's 100% repeatable.

Is there something I should be doing that I'm not doing, paint-wise or similar?

Thanks for any assistance.

like image 474
fyngyrz Avatar asked Dec 28 '15 00:12

fyngyrz


1 Answers

In general you should not update Qt controls from non UI thread, only a small amount of things is allowed to do regarding a painting in non UI thread - http://doc.qt.io/qt-4.8/threads-modules.html

If you need to update UI from non UI thread - use signals and slots (QueuedConnection or BlockingQueuedConnection connections, though make sure to not create deadlock with BlockingQueuedConnection). Or if you don't want to create additional signals and slots for some easy update - use invokeMethod (it can even return value and if you use it with BlockingQueuedConnection connection type, your thread will wait until UI is updated).

And a general advice - if you have a possibility - make one call for bulk of updates to UI instead of few small calls.

like image 189
Shf Avatar answered Oct 14 '22 23:10

Shf