Qt:没有从第二个线程调用插槽

Posted

技术标签:

【中文标题】Qt:没有从第二个线程调用插槽【英文标题】:Qt: slots are not being called from the second thread 【发布时间】:2018-03-25 17:09:24 【问题描述】:

我想从第二个线程更新 UI,我创建了将通过信号从其他线程调用的插槽,但不知何故它没有从其他线程调用。下面是代码:

WorkerThread.h

class WorkerThread: public QObject

    Q_OBJECT
public:
    WorkerThread();
    ~WorkerThread();

public slots:
    void onStart();
signals:
    void sendMessage(const QString& msg, const int& code);
;

WorkerThread.cpp

#include "workerwhread.h"

WorkerThread::WorkerThread()

void WorkerThread::onStart()
    emit sendMessage("start", 100);

用法:

MyWidget.h

namespace Ui 
class MyWidget;


class MyWidget: public QWidget

    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = 0);
    ~MyWidget();
private slots:
    void onGetMessage(const QString &msg, const int& code);
private:
    Ui::MyWidget *ui;
    QThread *thread = nullptr;
    WorkerThread *wt = nullptr;
;

MyWidget.cpp

MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget)

    ui->setupUi(this);
    wt = new WorkerThread;
    thread = new QThread;

    connect(thread, &QThread::finished, wt, &QObject::deleteLater);
    connect(ui->btStart, &QPushButton::clicked, wt, &WorkerThread::onStart);
    connect(wt, &WorkerThread::sendMessage, this, &MyWidget::onGetMessage);
    wt->moveToThread(thread);
    thread->start();

void MyWidget::onGetMessage(const QString &msg, const int& code)

    qDebug() << "message" << msg; // this never being called ????

注意:当我通过连接类型Qt::DirectConnectoin时,它可以工作,但问题是它不是GUI线程。

connect(wt, &WorkerThread::sendMessage, this, &MyWidget::onGetMessage, Qt::DirectConnection);

主要

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])

    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    w.setWindowIcon(QIcon(":/icons/system.png"));
    return a.exec();

【问题讨论】:

你运行 qmake 了吗?如果Qt::DirectConnection 有效,则很可能表明 Q_OBJECT 丢失或没有 QEventLoop 正在运行。正如您告诉 Qt::DirectConnection 正在工作 - 因此,您的插槽/信号连接很好。您放置了 Q_OBJECT 并有一个事件循环。所以没有明显的错误。 我无法重现您的问题:使用相同的代码,按下按钮时会打印message "start",因此会调用onGetMessage 插槽。贴出的代码似乎没有错误。 我知道代码真的很好很干净,而且我是编写干净和优化代码的大师,但是无论我做了什么,它仍然无法正常工作。我现在将对 Qt 单槽机制感到困惑。浪费了我很多时间。 QThread信号启动和WorkerThread中的对应槽之间应该有某种联系吗?也许线程只是在没有工作的情况下立即结束。见***.com/a/11039216/5781248 我在我的机器上测试了你的代码并且它工作正常,我使用的是 Qt 5.9.4,我在 Fedora 27 上运行,而不是MyWidget,我使用的是MainWindow ,您的工作环境如何? 【参考方案1】:

经过大量尝试和逐行检查代码,我终于找到了问题所在。原因是重写了QWidgetevent() 函数,event() 函数的返回值是bool,所以如果你返回一个true 它是可以的并且运行良好而不会抛出任何运行时或编译时错误。但它会阻止signal-slot 事件的发生。

所以不是return true,而是return QWidget::event(event);,那么它会解决这个问题。

【讨论】:

以上是关于Qt:没有从第二个线程调用插槽的主要内容,如果未能解决你的问题,请参考以下文章

多线程 dll 和 lock whan 从第二个线程调用函数

未调用 Qt 信号槽

Qt 插槽同时断开连接并从不同线程调用

C ++ Qt - 调用插槽时,该函数是不是称为新线程?

从第二个活动调用 sendMessage 方法

axios 调用从第一个 api 获取响应并传递到第二个 api