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】:
经过大量尝试和逐行检查代码,我终于找到了问题所在。原因是重写了QWidget
的event()
函数,event()
函数的返回值是bool
,所以如果你返回一个true
它是可以的并且运行良好而不会抛出任何运行时或编译时错误。但它会阻止signal-slot
事件的发生。
所以不是return true
,而是return QWidget::event(event);
,那么它会解决这个问题。
【讨论】:
以上是关于Qt:没有从第二个线程调用插槽的主要内容,如果未能解决你的问题,请参考以下文章