Qt信号和插槽如果从QRunnable或其他线程调用,则不起作用
Qt signal and slots do not work if called from QRunnable or another thread
我正在尝试学习如何在Qt中使用多线程,并将其用于QtWidget应用程序。所以我设置了这个简单的测试用例。
主窗口此窗体有一些按钮,每个按钮将执行另一个窗体(与此相关的对话框(。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->btnShowCalibrationDialog, &QPushButton::clicked,
this, [&](){
CalibrationDialog dlg;
dlg.exec();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
校准对话框 此对话框具有QPushButton
和QTextEdit
。单击按钮后,我将运行一个 QRunnable 类(接下来!
校准对话框.h(我省了你这些内涵和警卫!
class CalibrationDialog : public QDialog
{
Q_OBJECT
public:
explicit CalibrationDialog(QWidget *parent = nullptr);
~CalibrationDialog();
public slots:
void onBeginWorkRequested();
void onReceiveData(int data);
private:
Ui::CalibrationDialog *ui;
};
校准对话框.cpp
#include "worker.h"
CalibrationDialog::CalibrationDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::CalibrationDialog)
{
ui->setupUi(this);
connect(ui->btnBegin, &QPushButton::clicked,
this, &CalibrationDialog::onBeginWorkRequested);
}
CalibrationDialog::~CalibrationDialog()
{
delete ui;
}
void CalibrationDialog::onBeginWorkRequested()
{
qDebug() << "CalibrationDialog::onBeginWorkRequested()" << "on" << QThread::currentThreadId();
Worker* worker = new Worker();
QThreadPool* pool = QThreadPool::globalInstance();
connect(worker, &Worker::reportProgress,
this, &CalibrationDialog::onReceiveData);
pool->start(worker);
pool->waitForDone();
}
void CalibrationDialog::onReceiveData(int data)
{
ui->teResults->append(QString::number(data));
ui->teResults->ensureCursorVisible();
}
工人这是一些可运行的...我想报告进度,以便以响应方式显示在对话框的文本编辑中!
工人.h
class Worker : public QObject, public QRunnable
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
void run() override;
private:
int mProgress = 0;
signals:
void reportProgress(int progress);
};
工人.cpp
Worker::Worker(QObject *parent) : QObject(parent)
{
}
void Worker::run()
{
qDebug() << "Worker is running #" << QThread::currentThreadId();
while(true) {
mProgress += 100;
emit reportProgress(mProgress);
QThread::msleep(500);
}
}
我在调试器中看到控件进入 while 循环......但是对话没有处理信号!我的意思是文本编辑保持空白!
我尝试阅读文档并在线搜索...我得出的结论是,我的问题在于线亲和力的荒地......但我不知道是否是这种情况,如果是这样,如何解决它。请协助!
删除pool->waitForDone();
,切勿在GUI中使用waitForX方法,因为它们会阻止信号完成其工作。
相关文章:
- 类与私有变量的其他类之间的线程安全性
- 当我在其中一个线程执行中(在activemq-cpp中)捕获到特定值时,我如何终止/停止所有其他线程
- MESI协议和std::atomic-它是否确保所有写入立即对其他线程可见?
- 线程消息传递或更好:在"大师班"中访问其他班级的成员
- 锁定来自其他线程的类成员
- 使来自线程的数据流对所有其他线程都可读
- Qt信号和插槽如果从QRunnable或其他线程调用,则不起作用
- 当只有一个线程主要使用该对象而其他线程很少使用它时,如何最小化该对象的互斥锁锁定?
- 视频在唤醒其他线程时输入设备断开连接
- 如何从其他线程 winapi 获取消息
- 将抽象对象从主线程发送到其他线程
- 使用 std::condition_variable 触发其他线程.使用哪些互斥锁?
- 在其他线程中循环访问该concurrent_vector时调用 concurrency::concurrent_vect
- 生成线程并在运行时执行其他操作,只要它处于活动状态
- C++如何判断互斥体在阻塞其他线程时是否被单个线程不成比例地占用
- tbb::enumerable_thread_specific在其他线程库中工作吗
- 当其他线程正在编写线程安全时,我是否必须互斥读操作
- 无法从其他线程播放QMediaPlayer
- 无法修改其他线程中 ref 传递的值
- 其他线程堆栈上的可用内存无效