c++ - 在另一个 QThread 上运行成员方法时,无法将事件发送到不同线程拥有的对象
问题描述
我需要在我的 MainWindow 类中运行一个方法,在不同的线程中,因为它是一个耗时的过程。
这是我尝试过的:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
initGui(ui);
// Create background worker thread
backgroundWorker = QThread::create([this] {
backgroundMethod();
});
// Define when finished with work
connect(backgroundWorker, &QThread::finished, [this] () {
qDebug() << "Background method has finished";
// Stop movie
ui->lblLoading->movie()->stop();
// go to next screen
ui->tabbarMainWidget->tabBar()->setCurrentIndex(1);
//show backup icon files
if(filesToBackup.size() > 0) {
qDebug() << "There are files to backup!";
ui->lblInfoImage->show();
}
});
// Start worker thread
backgroundWorker->start();
}
背景方法
void MainWindow::backgroundMethod() {
for (int i = 0; i < 10; i++) {
qDebug() << "Hello World";
}
}
我省略了很多代码,因为它不是必需的。基本逻辑如下:
使用QThread::create()启动新线程
运行
backgroundMethod()
直到完成,同时让 UI 可用于其他工作。完成
backgroundMethod()
后,QThread
应该发出finished()信号。我在
backgroundWorker
线程finished()
和 lambda 之间建立了一个连接设置来运行更多代码。
问题:
后台方法已完成
QObject::killTimer:定时器不能从另一个线程停止
QCoreApplication::sendEvent 中的 ASSERT 失败:“无法向其他线程拥有的对象发送事件。当前线程 0x0x2801d950。接收器 'lblInfoImage'(类型为 'QLabel')在线程 0x0x2688c4b0 中创建”,文件 kernel\qcoreapplication.cpp,行578 04:11:28:程序意外结束。
简而言之,我正在访问lblInfoImage
线程backgroundWorker
。我知道使用信号/插槽机制应该可以解决这个问题,我对它的使用是正确的。
我不确定为什么会发生这种情况,我需要一些帮助来了解我做了什么导致问题以及如何解决它
解决方案
问题很简单:您在非 UI 线程上执行 UI 代码,这在 Qt(以及许多其他跨不同语言的 UI 框架中)是严格禁止的。发生这种情况是因为您连接错误:
connect(backgroundWorker, &QThread::finished, [this] () {
...
});
该连接意味着:每当QThread
发出finished
信号时运行此功能。问题是,它将在发出的信号的上下文中运行函数,这是另一个线程不是线程backgroundWorker
所在的线程。所以你必须提供 UI 线程上下文来接收这个信号:
connect(backgroundWorker, &QThread::finished, this, [this] () {
...
});
现在提供的函数将在 UI 线程 ( this
) 的上下文中执行。
推荐阅读
- java - 未知主机异常 Spring boot
- jestjs - 如何在 package.json 中设置 JestJS 全局超时
- .net - 是否可以从 Dotliquid 访问嵌套字典?
- javascript - 显示分数后重新开始测验
- javascript - 为什么 Onclick 事件在我的 ion col 上不起作用?
- html - 将图像数据设置为要在 HTML 伪元素中使用的自定义 ISO 字符
- python - 为什么如果手动激活程序但不能作为使用 crontab、mysql 和 python 的守护程序激活,程序会运行良好?
- ios - 找不到 -lAppAuth 的库
- c - C 分叉和进程,¿为什么需要这个?
- octave - 在 Octave 中使用稀疏矩阵广播乘法/除法