传递QModelIndex跨线程排队连接
WMIQuery::wmiquery(WMI::WMITable* table, const QString& query, WMI::ProgressIndicator* progressIndicator)
这是函数签名。我通过 QtConcurrent::run 调用它。
QFuture<quint32> future = QtConcurrent::run(WMI::WMIQuery::wmiquery, _table, query);
架构非常简单。 查询将返回的预期行数是已知的。 查询是并行运行的,并且在每条记录上获取一行都会添加到表:WMI::WMITable* WMI::WMITable
是一个简单的 QObject 表数据结构。 添加行时,它会发出 rowsAboutToBeInserted(QModelIndex, int, int)
和 rowsInserted(QModelIndex, int, int)
。
另一方面, ProgressIndicator
在主线程上实例化,并且 table
被传递给它的 ctor
。它从 WMI::WMIQuery::wmiquery()
到 ProgressIndicator::setRecordCount(quint64 count)
获取预期的总行数。 它有一个槽 rowAdded()
,它通过做一些简单的数学运算来发出 100 的进度。它在它的构造中连接了
connect(_table, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowAdded()));
我的想法。由于 WMI::WMIQuery::wmiquery()
我在不同的线程上运行(在 QThreadPool
上),此连接是跨线程排队连接。我说得对吗?
我在运行时收到以下错误
QObject::connect:无法对“QModelIndex”类型的参数进行排队
(确保使用 qRegisterMetaType() 注册“QModelIndex”。)
我应该做什么?因为我的 SLOT(rowAdded()) 不需要 SIGNAL(rowsInserted(QModelIndex,int,int)) 的 3 个参数,我应该制作另一个像 rowInserted 的信号() 并在我发出 rowsInserted(QModelIndex,int,int)
时发出它,并使用此 SIGNAL
代替此连接
您可能会问为什么我在表数据结构中使用像 rowsInserted(QModelIndex,int,int) 这样的模型信号。因为我也有一个连接到该表的模型。这也将逐行更新。但我认为这在这方面是不重要的。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在使用非平凡的参数类型(例如 QModelIndex )跨线程边界发出信号之前,您必须首先调用以下命令:
这使得 Qt 能够跨线程边界发出信号。
通常,您会在
main()
或仅运行一次的地方执行此操作,在调用emit
之前,但在之后您的QApplication
已实例化。这仅对于不平凡的类型是必要的。例如,像这样的信号不需要您调用
qRegisterMetaType()
但是像这样的信号确实需要
qRegisterMetaType()
:有关详细信息,请参阅此处的 Qt 文档: http://doc.qt.nokia .com/latest/qmetatype.html#qRegisterMetaType
Before emitting a signal across a thread boundary with a non-trivial argument type (like
QModelIndex
), you must first call this: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 callingemit
, but after yourQApplication
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()
But a signal like this does require
qRegisterMetaType()
:For more info, see the Qt docs here: http://doc.qt.nokia.com/latest/qmetatype.html#qRegisterMetaType
我知道这已经很晚了,但我想确保有人提到过它: QModelIndex 并不意味着要排队,出于同样的原因,它不意味着以后以其他方式存储和使用。也就是说,如果模型在使用 QModelIndex 之前发生更改,您将得到未定义的行为。如果您需要带有模型索引的排队事件,您可能应该使用 QPersistentModelIndex。与原来的问题并不真正相关,但可能对登陆这里的人有用。
I know this is rather late, but I wanted to be sure someone mentioned it: QModelIndex is not meant to be queued, for the same reason that it's not meant to be stored and used later in other ways. That is, if the model changes before you use the QModelIndex, you will get undefined behavior. If you need queued events with model indices, you should probably use QPersistentModelIndex. Not really relevant to the original question, but may be of use to someone who lands here.