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”类型

  1. 对于用户定义的类型,您可以使用(请阅读https://doc.qt.io/qt-5/qmetatype.html

    Q_DECLARE_METATYPE(ErrorCode);

  2. 使用标准类型作为参数(int,QMap,QString ....)

以上是关于QThread如何从其自己的线程发送一个带有枚举作为QML消耗参数的信号?的主要内容,如果未能解决你的问题,请参考以下文章

带有 QThread 和线程模块的 Python 多线程

QThread 与 QObject的关系(QObject可以用于多线程,可以发送信号调用存在于其他线程的slot函数,但GUI类不可重入)

Qt QThread与QObject的关系

如何向 Qt 中 QThread 类的特定对象发出信号?

QThread 与 QObject的关系?

QThread 和 GUI 线程说明