WMIQuery::wmiquery(WMI::WMITable* table, const QString& query, WMI::ProgressIndicator* progressIndicator)
This is the Function signature. and I am calling it through QtConcurrent::run
QFuture<quint32> future = QtConcurrent::run(WMI::WMIQuery::wmiquery, _table, query);
The architecture is quite simple.
Expected number of rows that will be returned by the query is known.
query is ran parallelly and on each record fetch a row is added to table: WMI::WMITable*
WMI::WMITable
is a Simple QObject Table Data Structure .
it emits rowsAboutToBeInserted(QModelIndex, int, int)
and rowsInserted(QModelIndex, int, int)
upon row addition.
On the other hand ProgressIndicator
in instantiated on main thread and the table
is passed to its ctor
. it gets the expected total number of rows from WMI::WMIQuery::wmiquery()
through ProgressIndicator::setRecordCount(quint64 count)
.
it has a slot rowAdded()
which emits the progress out of 100 by doing some simple mathematics. In its ctor it connects
connect(_table, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowAdded()));
What I think. as WMI::WMIQuery::wmiquery()
i running on a different thread (on QThreadPool
) this connection is a cross thread queued connection . am I correct ?
I am getting the following error at runtime
QObject::connect: Cannot queue arguments of type 'QModelIndex'
(Make sure 'QModelIndex' is registered using qRegisterMetaType().)
What should I do ? as my SLOT(rowAdded())
does not require the 3 arguments of SIGNAL(rowsInserted(QModelIndex,int,int))
should I make another signal like rowInserted()
and emit it whenever I am emitting rowsInserted(QModelIndex,int,int)
and use this SIGNAL
instead for this coinnection
You may ask why I am using model like signals like rowsInserted(QModelIndex,int,int)
in the table data structure. cause I do also have a model that is connected to this table. which will also be updated row by row. however I think that is immater in this regard.
Before emitting a signal across a thread boundary with a non-trivial argument type (like QModelIndex
), you must first call this:
qRegisterMetaType<QModelIndex>("QModelIndex");
That prepares Qt to be able to emit the signal across a thread boundary.
Normally you would do this in main()
or somewhere that only runs once, before calling emit
, but after your QApplication
has been instantiated.
This is only necessary for types that are non-trivial. For example, a signal like this would not require you to call qRegisterMetaType()
signals: void mySignal(int foo, int bar);
But a signal like this does require qRegisterMetaType()
:
signals: void mySignal(QModelIndex);
For more info, see the Qt docs here: http://doc.qt.nokia.com/latest/qmetatype.html#qRegisterMetaType