QThread如何从其自己的线程发送一个带有枚举作为QML消耗参数的信号?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QThread如何从其自己的线程发送一个带有枚举作为QML消耗参数的信号?相关的知识,希望对你有一定的参考价值。
在下面的代码中,如果从主线程发出信号errorHappened
,则它的工作没有问题。但是,如果它是从QThread
线程发出的,则会失败,并显示以下错误:
QObject::connect: Cannot queue arguments of type 'ErrorCode'
(Make sure 'ErrorCode' is registered using qRegisterMetaType().)
是否有一种方法可以成功地从QThread
线程发出信号?如果是这样,如何?
MyClass.h
#import <QThread>
#import <atomic>
class MyClass : public QThread
{
Q_OBJECT
public:
enum ErrorCode {
ErrorA,
ErrorB,
ErrorC
};
Q_ENUM(ErrorCode)
signals:
void errorHappened(ErrorCode errorCode);
public slots:
void mainThreadError();
void otherThreadError();
private:
std::atomic<bool> m_running;
std::atomic<bool> m_signalStop;
std::atomic<bool> m_signalError;
void run() override;
...
};
MyClass.cpp摘录
void MyClass::mainThreadError()
{
emit errorHappened(ErrorCode::ErrorA);
}
void MyClass::otherThreadError()
{
m_signalError = true;
}
void MyClass::run()
{
m_running = true;
while (!m_signalStop) {
if (m_signalError) {
emit errorHappened(ErrorCode::ErrorA);
m_signalError = false;
}
msleep(1);
}
m_running = false;
m_signalStop = false;
}
main.cpp摘录
qmlRegisterType<MyClass>("MyClass", 1, 0, "MyClass");
main.qml
import MyClass 1.0
...
MyClass {
id: tester
onErrorHappened: {
var s
switch (errorCode) {
case MyClass.ErrorA:
s = "Error A happened"
break;
...
}
console.log(s)
}
}
...
Button {
text: "Test on main thread"
onClicked: tester.mainThreadError()
}
Button {
text: "Test on other thread"
onClicked: tester.otherThreadError()
}
}
答案
仅在线程(不是在主线程中)中定义的“ ErrorCode”类型
对于用户定义的类型,您可以使用(请阅读https://doc.qt.io/qt-5/qmetatype.html)
Q_DECLARE_METATYPE(ErrorCode);
使用标准类型作为参数(int,QMap,QString ....)
以上是关于QThread如何从其自己的线程发送一个带有枚举作为QML消耗参数的信号?的主要内容,如果未能解决你的问题,请参考以下文章
QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)