PDA

View Full Version : Sharing data across threads



jphn_crichton
27th April 2008, 21:20
Hello,
I am new to Qt and it could be that the answer to my question is really simple but still I can't find it. I have two threads in my application. One of them is gui thread and the other is database query thread. I have queued connections between these two and they work fine but I need to share data across them. I tried to use Q_DECLARE_METATYPE macro

Q_DECLARE_METATYPE (QSqlQueryModel)
and I get the following error:

/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qabstractitemmodel.h: In copy constructor 'QSqlQueryModel::QSqlQueryModel(const QSqlQueryModel&)':
/usr/local/Trolltech/Qt-4.3.4/include/QtSql/qsqlquerymodel.h:60: instantiated from 'void* qMetaTypeConstructHelper(const T*) [with T = QSqlQueryModel]'
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmetatype.h:151: instantiated from 'int qRegisterMetaType(const char*, T*) [with T = QSqlQueryModel]'
database.h:62: instantiated from here
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qabstractitemmodel.h:324: error: 'QAbstractTableModel::QAbstractTableModel(const QAbstractTableModel&)' is private
/usr/local/Trolltech/Qt-4.3.4/include/QtSql/qsqlquerymodel.h:60: error: within this context
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmetatype.h: In function 'void* qMetaTypeConstructHelper(const T*) [with T = QSqlQueryModel]':
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmetatype.h:126: note: synthesized method 'QSqlQueryModel::QSqlQueryModel(const QSqlQueryModel&)' first required here
I know that later I need to use qRegisterMetatype function but I even didn't get that far.
I am using linux/gcc with eclipse and Qt 4.3.
Thank you in advance for any help you offer.

wysota
27th April 2008, 21:35
QSqlQueryModel already has a metatype declared. Whatever you are doing, it will probably not work as database connections can't be shared across threads. If you are trying to pass the model to another thread using signals and slots, it will not work too, because QObject subclasses can't be copied and that's required when using signal-slot connections across threads.

john_crichton
28th April 2008, 13:30
Ok, thank you for your reply. I have an application that manipulates database in one thread and post results in another thread (the gui thread). So basicly I execute a query in query thread and then I need to pass the result data to the gui thread. Do you have any idea how this might work? Thanks in advance.

wysota
28th April 2008, 13:44
Pass the data, not the model. You can either use signals and slots or events to do that. But why do you have to use a separate thread just to query the database for data? Can't you do that all in a single thread?

john_crichton
28th April 2008, 20:29
The database can get quite big and I don't want the application to hang while it executes queries. At the moment I am using signals and slots across threads with queued connection. I can send const QString &query_string from the gui thread to the query thread but I don't know how to send the queried data back. Can you tell me what data structure would be the best for this job? For now, I will try to send some test data across threads. Thanks in advance.

wysota
28th April 2008, 21:09
Can you tell me what data structure would be the best for this job?
How about QSqlRecord or QVariantList?

john_crichton
29th April 2008, 21:27
I am trying to use QSqlRecord but I can't get it shared across threads. I try to use qRegisterMetaType

qRegisterMetaType("My Type", QSqlRecord);
and I get the following error:

main.cpp:30: error: expected primary-expression before ')' token
I am using linux/gcc with eclipse and Qt 4.3.
Do you know what can be the problem. Thanks in advance.

wysota
29th April 2008, 22:53
It should be: qRegisterMetaType<QSqlRecord>("QSqlRecord")

john_crichton
30th April 2008, 15:23
Thank you. Now I can share QSqlRecord across threads. And now I have deeper understanding of how things are done in Qt and I think of Model/View architecture. Now, since models can't be shared across thread that means that I need to have one model in the gui thread. Then I could feed it with data from the query thread. Do you know how to feed the model with data? There is a method setData and I am trying to get it to work at the moment but I would appreciate any help you offer. Thanks in advance.

john_crichton
2nd May 2008, 20:21
I found a solution. I send model pointer (QSqlQueryModel*) across thread.

wysota
4th May 2008, 21:09
Do you know how to feed the model with data? There is a method setData and I am trying to get it to work at the moment but I would appreciate any help you offer.
You can't use setData directly from another thread - this method is not thread safe. You can use signals and slots for safe data transport.


I found a solution. I send model pointer (QSqlQueryModel*) across thread.

You're asking for trouble.

john_crichton
5th May 2008, 19:29
Hi, I know that it is unsafe to send pointers across threads. That is why I posted another question here http://www.qtcentre.org/forum/f-qt-programming-2/t-protect-qsqlquerymodel-in-two-threads-13358.html.
Thank you in advance for any new help you offer.