首页 > 解决方案 > 从 QThread 工作类发出的信号没有到达

问题描述

我有这个简化的代码:

class MyCustomObject {
};

class DeviceConnection : public QObject {
    Q_OBJECT

    public:
        explicit DeviceConnection(QObject* const parent = nullptr);

    signals:
        void readFinished(MyCustomObject result);

    public slots:
        void readFromDevice();
};

DeviceConnection::readFromDevice() {
    /* ... */
    emit readFinished(MyCustomObject());
}

void MainWindow::on_actionRead_triggered() {
    QThread* const thread = new QThread(this);
    DeviceConnection* const connection = new DeviceConnection();
    connection->moveToThread(thread);
    thread->start();

    connect(connection, &DeviceConnection::readFinished, this, [=](MyCustomObject data) {
        /* This never runs. */
        connection->deleteLater();
        thread->quit();
    });

    QTimer::singleShot(0, connection, &DeviceConnection::readFromDevice);
}

这开始阅读就好了。我可以在调试器中看到我正在到达这emit条线,并且我正在这条线中到达那里。但我也可以在调试器和代码行为中看到,readFinished从未调用过 lambda。对于不是 lambdas 的插槽也是如此。有什么问题?

编辑:当我不使用额外的线程时,此代码运行良好,但当然它在readFromDevice()运行时会阻塞主线程。

标签: qtqt5qthread

解决方案


我想到了。不幸的是,当我第一次问这个问题时,我简化了重要的部分,但我只是把它重新编辑了。

问题是MyCustomObject不能在 Qt 消息队列中排队。为此,您需要运行以下命令:

qRegisterMetaType<MyCustomObject>("MyCustomObject");

或者

// ideally just after the definition for MyCustomObject
Q_DECLARE_METATYPE(MyCustomObject);

// any time before you want to enqueue one of these objects
qRegisterMetaType<MyCustomObject>();

推荐阅读