首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在运行另一个QThread上的成员方法时,无法将事件发送到其他线程所拥有的对象

在运行另一个QThread上的成员方法时,无法将事件发送到其他线程所拥有的对象
EN

Stack Overflow用户
提问于 2019-08-30 02:19:33
回答 1查看 1.2K关注 0票数 0

我需要在我的MainWindow类中以不同的线程运行一个方法,因为它是一个长度和时间消耗的过程。

这就是我试过的:

代码语言:javascript
复制
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();
}

backgroundMethod

代码语言:javascript
复制
void MainWindow::backgroundMethod() {
    for (int i = 0; i < 10; i++) {
        qDebug() << "Hello World";
    }
}

我省略了大量的代码,因为这是不必要的。基本逻辑如下:

  1. 使用QThread::create()启动新线程
  2. 运行backgroundMethod(),直到完成,同时使UI免费用于其他工作。
  3. backgroundMethod()完成时,QThread应该发出完成()信号。
  4. 我在backgroundWorker线程的finished()和lambda之间建立了连接,以运行更多的代码。

问题:

背景法已经完成 QObject::killTimer:定时器不能从另一个线程停止 QCoreApplication中的断言失败::sendEvent:“无法向其他线程拥有的对象发送事件。当前线程0x0x2801d950。在线程0x0x2688c4b0中创建了接收器'lblInfoImage‘(类型为'QLabel')”,文件kernel\qcoreapplication.cpp,第578行04:11:28:程序意外完成。

简而言之,我正在访问lblInfoImage线程上的backgroundWorker。我知道使用信号/槽机构应该能解决这个问题,而我对它的使用是正确的。

我不知道为什么会发生这种情况,,我需要一些帮助来理解我所做的导致问题的原因,以及我如何修复它

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-30 06:04:16

问题很简单:您在一个非UI线程上执行UI代码,这在Qt中是严格禁止的(以及在许多其他不同语言的UI框架中)。发生这种情况是因为您做错了连接:

代码语言:javascript
复制
connect(backgroundWorker, &QThread::finished, [this] () {
    ...
});

这种连接意味着:每当QThread发出finished信号时,运行此函数。问题是,它将在发出的信号的上下文中运行函数,这是另一个线程,而不是backgroundWorker驻留的线程。因此,您必须提供UI线程上下文来接收此信号:

代码语言:javascript
复制
connect(backgroundWorker, &QThread::finished, this, [this] () {
        ...
    });

现在,提供的函数将在UI线程(this)的上下文中执行。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57719723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档