传递QModelIndex跨线程排队连接

发布于 2024-11-19 12:50:25 字数 1515 浏览 2 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七秒鱼° 2024-11-26 12:50:25

在使用非平凡的参数类型(例如 QModelIndex )跨线程边界发出信号之前,您必须首先调用以下命令:

qRegisterMetaType("QModelIndex");

这使得 Qt 能够跨线程边界发出信号。

通常,您会在 main() 或仅运行一次的地方执行此操作,调用 emit 之前,但在之后您的QApplication 已实例化。

这仅对于不平凡的类型是必要的。例如,像这样的信号需要您调用qRegisterMetaType()

信号:
   void mySignal(int foo, int bar);

但是像这样的信号确实需要qRegisterMetaType()

信号:
   无效 mySignal(QModelIndex);

有关详细信息,请参阅此处的 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:

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

并安 2024-11-26 12:50:25

我知道这已经很晚了,但我想确保有人提到过它: 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文