Qt Update Gui From Worker Thread

  воскресенье 23 сентября
      76

The instruments are very easy to read at night and everything is exactly where it should be. Even without the additional gauges this helicopter is far more controllable and nice to fly than any other we tested so far. Eurocopter helicopter models. As the real world counterpart, we had no problems flying in full IFR conditions and even do ILS approaches.

The Qt GUI must run in this thread. All widgets and several related classes, for example QPixmap, don't work in secondary threads. A secondary thread is commonly referred to as a 'worker thread' because it is used to offload processing work from the main thread.

As the title's question, I wrote a program to render the complex graphics at a sub-thread (want not to occupy much cpu time for the GUI thread in order to speed up user interaction response) into a QImage, after that in this sub-thread render call stack, call update() directly to let QT deliver a queued connection (I guess it act as this) which lead to a QWidget::paintEvent in GUI thread to drawImage to the widget. This do works, but I found after running a while, occasionally, the GUI thread did not response to the update() call by the sub-thread (means i called update(), but no paintEvent received), but only response to the system level update/paintEvent cycle (for example, get/lose focus of the main window).

I took a glance at the QT code, seems the system's updatePending member var is true that causes the QT ignores my update call. But i am not sure. Can any friend tell me whether the update() is designed to be able to called in sub-thread other than GUI? [quote author='JKSH' date=']No. GUI classes are designed to be manipulated from the main thread only ( update() counts as manipulation). That's why the main thread is also called the 'GUI thread'. From: [quote].the GUI classes, notably QWidget and all its subclasses, are not reentrant.

They can only be used from the main thread.[/quote][/quote] Hi, JKSH, there is still a official statement in the link you provided: 'In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished. This is the approach used for implementing the Mandelbrot and the Blocking Fortune Client example.' So I think the way of painting a QImage in sub-thread, and do a BitBlt like copy to the Widget in GUI thread is an way. The key is, could I call update() directly in sub-thread, or have to write a signal/slot on my class to queue the update() call to the GUI thread? [quote author='KA51O' date=']But this is does not (at least for me) adress the problem that GUI objects like e.g. QWidget are not allowed to be modified directly from another thread than the main thread.[/quote] Thats the point of queued connections: they do no direct manipulation! Basically an event is generated and sent to the object and the object executes the desired method 'on itself'.

Qt Update Gui From Worker Thread

Thus there is no conflict between those 2 threads and also no relationship between the sender and receiver object. Hi KA51O, I think raven-worx is right. I think you've mixed up 'signal emission' with 'widget manipulation'. In simple terms, 'Manipulate' == 'Modify member variables'. Let's follow the logic of a simple case: A queued signal is emitted from a worker thread.

The slot -- QWidget::update() -- executes in the context of the GUI thread The slot contains code that modifies the QWidget's member variables. Question: Which thread modifies those member variables? Answer: The GUI thread (because the slot is running in the GUI thread) Conclusion: Even though the signal was emitted from the worker thread, the QWidget is manipulated by the GUI thread. To look at it from a different angle, here's why widget manipulation from a worker thread causes problems: • The OS's graphics system runs in the GUI thread, and reads the QWidget's member variables from the GUI thread. • If member variables are modified by a worker thread, they could be modified while the graphics system is in the middle of reading those variables • Therefore, a QWidget's member variables must not be modified from a worker thread; a QWidget must not be manipulated from a worker thread. The description above is oversimplified, but I hope that makes it understandable for you?:).