PDA

View Full Version : Loading (e. g. a qtreeview) model data in a different thread



dubbaluga
31st March 2011, 23:00
Hi,

I stumbled over this thread: http://www.qtcentre.org/threads/32539-QTreeView-Creating-an-animated-busy-icon-whilst-loading-data and it seems this problem is similar to mine. The solution proposed in this related thread does not help me much (because I don't know how it was implemented). But maybe I don't get some basic concept of Qt or graphical frameworks in general. How is it possible to load data in a separate thread so that the GUI does not block?

On one hand data that is loaded in a dedicated thread cannot be used in the main GUI-thread (Error: "QObject: Cannot create children for a parent that is in a different thread."). On the other hand I don't know how the main GUI-thread knows when (e. g. by initiating the widget to reload the model itself) and how (e. g. by setModel() with valid data from the same or a different thread) to use the new model.

Actually I just want to load vast amounts of data in a dedicated thread to display a "loading" picture or something similar until the data has become available so that the user knows what's going on.

Thanks for your help and best regards,
Rainer

wysota
31st March 2011, 23:56
On one hand data that is loaded in a dedicated thread cannot be used in the main GUI-thread (Error: "QObject: Cannot create children for a parent that is in a different thread.").
Not every "data" is a QObject. The model itself belongs to the main thread but it doesn't mean data for it can't be prepared in another thread.


Actually I just want to load vast amounts of data in a dedicated thread to display a "loading" picture or something similar until the data has become available so that the user knows what's going on.
So where does the thread fit in?

dubbaluga
1st April 2011, 22:53
Hi,

thanks for your quick reply!


Not every "data" is a QObject. The model itself belongs to the main thread but it doesn't mean data for it can't be prepared in another thread. So where does the thread fit in?

I'm not completely sure, but I would pass a reference of the QAbstractItemModel from the "main thread" to the "data preparing" thread. This thread (the latter) in turn adds QModelindex objects (as they contain the internal void* pointer) by value to e. g. the setData()-method of that model.

Could it work that way?

Best regards,
Rainer

wysota
1st April 2011, 23:09
I'm not completely sure, but I would pass a reference of the QAbstractItemModel from the "main thread" to the "data preparing" thread. This thread (the latter) in turn adds QModelindex objects (as they contain the internal void* pointer) by value to e. g. the setData()-method of that model.

Could it work that way?

No, that's not a good idea. You should prepare the data in external thread and signal the model object that it can consume what's prepared for it so that the modification to the model happens in the main thread.

dubbaluga
2nd April 2011, 12:55
No, that's not a good idea. You should prepare the data in external thread and signal the model object that it can consume what's prepared for it so that the modification to the model happens in the main thread.

So, it's working for me now. I'm passing the underlying data structure of my QAbstractItemModel object, which is an instance of a composite pattern (http://en.wikipedia.org/wiki/Composite_pattern) class to the worker thread so that it can add additional elements to it.
Before doing so, the beginResetModel() method is invoked. After adding the elements, the endResetModel() method of my QAbstractItemModel instance is invoked.

What helped me a lot was actually the point, that GUI parts have to stay in the main thread (GUI thread). In case I want to display some "work in progress" message, I'm using Signals/Slots between my worker thread and main thread, as mentioned here (http://doc.trolltech.com/4.7/threads-qobject.html#signals-and-slots-across-threads).

As I'm actually programming with PySide, further relevant links can be found here:

Signals and Slots in PySide (http://developer.qt.nokia.com/wiki/Signals_and_Slots_in_PySide)
How to emit cross-thread signals in Qt (C++) (http://stackoverflow.com/questions/638251/how-to-emit-cross-thread-signal-in-qt)
New-style signals: no Signal.connect()? (http://groups.google.com/group/pyside/browse_thread/thread/80594d5402301db3)


Thanks for your help! Best regards, Rainer

wysota
2nd April 2011, 13:03
I'm not convinced what you are doing is good. You are manipulating the same data structure from two threads without proper synchronization. This is prone to race conditions and can crash your application or make it behave weird.