PDA

View Full Version : [QStandardItemModel] read from a different thread



mentalmushroom
8th November 2011, 08:24
Hello. I use model-view-conroller pattern in my project. Controller is a different thread running in a background, sometimes it needs to loop through the data stored in model and make some processing, but as long as it is a different thread I don't know how to do this in a safe way. Could you, smart people, give me some advice?

Santosh Reddy
9th November 2011, 06:06
The better way is keep model in the GUI thread, and move only the long processing loop to different thread.
View will take data from model, model if required will trigger the processing loop and continue, once the loop is finished it should inform the model using a signal, and model should update the view with new data.

mentalmushroom
9th November 2011, 11:03
Thanks for your reply, but my question was rather regarding controller. Model and view are in the same thread, but controller works in a different thread, where it needs to get some data from the model. I decided to create an additional class that wraps QStandardItemModel and added methods like to keep it thread safe:



// data model

class MyDataModel: public QObject
{
public:
QList<SomeDataItem> getItems() const;

protected:
QStandardItemModel standardModel;
}

QList<SomeDataItem> MyDataModel::getItems() const
{
QList<SomeDataItem> items;
if (standardModel->thread() == QThread::currentThread())
{
// ... gather data in a usual way
}
else
{
// invoke it and wait until finished
QMetaObject::invokeMethod(this, "getItems", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QList<SomeDataItem>, items));
}
return items;
}




// controller

Controller::run() // different thread
{
//
QList<SomeItem> items = model->getItems();
// ... do processing...
}


Only I am not sure it is the good way to do that. However, I didn't find any explanation regarding multithreaded model-view-controller.

Santosh Reddy
9th November 2011, 23:49
// invoke it and wait until finished
QMetaObject::invokeMethod(this, "getItems", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QList<SomeDataItem>, items));

Invoke and continue / return don't wait (that is purpose of multi-threading). When the thread is done let it emit a signal and wait for the model to read the data.

mentalmushroom
10th November 2011, 10:33
hmmm... not sure what you meant "return don't wait". it should wait for return due to Qt::BlockingQueuedConnection, as far as i understood documentation. yes, it would be possible to emit signal from controller and continue until model emits reply signal, but it gets a bit complicated comparing to just call and wait, because controller can't continue without that data anyway.

Added after 1 45 minutes:

Ok, sorry, i think, i understood what you meant. QMetaObject::invokeMethod didn't work with Qt::BlockingQueuedConnection when i tried to return some result.