WMIQuery::wmiquery(WMI::WMITable* table, const QString& query, WMI::ProgressIndicator* progressIndicator)
这是功能签名。我通过QtConcurrent::run
QFuture<quint32> future = QtConcurrent::run(WMI::WMIQuery::wmiquery, _table, query);
架构非常简单。
将知道查询将返回的预期行数。
并行运行查询并在每个记录上获取一行添加到table: 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)
这样的信号模型。因为我也有一个连接到这个表的模型。它也将逐行更新。但是我认为在这方面这是更加明确的。
答案 0 :(得分:2)
在使用非平凡的参数类型(如QModelIndex
)跨线程边界发出信号之前,必须先调用它:
qRegisterMetaType<QModelIndex>("QModelIndex");
准备Qt能够在线程边界发出信号。
通常情况下,您会在main()
或仅运行一次的地方执行此操作,在调用emit
之前,但在之后 QApplication
已被实例化。
这仅适用于非平凡的类型。例如,像这样的信号不要求您拨打qRegisterMetaType()
signals: void mySignal(int foo, int bar);
但像这样的信号需要qRegisterMetaType()
:
signals: void mySignal(QModelIndex);
有关详细信息,请参阅此处的Qt文档:http://doc.qt.nokia.com/latest/qmetatype.html#qRegisterMetaType
答案 1 :(得分:2)
我知道这已经很晚了,但我想确定有人提到它:QModelIndex并不意味着排队,原因与以后其他方式无意存储和使用有关。也就是说,如果在使用QModelIndex之前模型发生更改,您将获得未定义的行为。如果您需要具有模型索引的排队事件,则应该使用QPersistentModelIndex。与原始问题不太相关,但可能对在此居住的人有用。