qt 子线程(多线程)更新gui的几种方法

直接进入主题,据我所知,方法有3种:

1、自定义signal、slot,这个就不多说了,标准方法

2、使用QmetaMethod::invoke,这是可以直接在子线程调用的,看起来比较另类

3、从5.4开始,有了另一种新方法:Qtimer::singleShot(0),这玩意儿可不是定时启动那么简单,你给他0的时间他就是GUI线程安全的,完整例子可以测试:

#include <QCoreApplication>#include <QTimer>
#include <QDebug>
#include <thread>
#include <QThread>
#include <QEventLoop>
#include <QThread>
using std::thread;

class TestObj
        :public QObject
{
// Used new connect syntax no need for Q_OBJECT define
// you SHOULD use it. I used just to upload one file
//Q_OBJECT
public slots:
    void doWork()
    {
        qDebug() << "QThread id" << QThread::currentThreadId();
        QTimer::singleShot(0, qApp, []()
        {
            qDebug() << "singleShot from QThread" << QThread::currentThreadId();
        });
    }
};


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main thread id" << QThread::currentThreadId();

    thread testThread([]()
    {
        QEventLoop loop;
        Q_UNUSED(loop)
        qDebug() << "std::thread id" << QThread::currentThreadId();

        QTimer::singleShot(0, qApp, []()
        {
            qDebug() << "singleShot from std thread with qApp" << QThread::currentThreadId();
        });

        qDebug() << "std::thread finished";
    });
    testThread.detach();

    QThread testQThread;
    TestObj testObj;
    testObj.moveToThread(&testQThread);
    QObject::connect(&testQThread, &QThread::started, &testObj, &TestObj::doWork);
    testQThread.start();

    // 下列方法2选1,都可以退出app    
    //QMetaObject::invokeMethod(&a, "quit", Qt::QueuedConnection);
    QTimer::singleShot(0, &a, [&a]()
    {
        a.quit();
    });

    // 直接调用a.quit();是无法退出的,因为没有到eventloop
    // a.quit();
    a.exec();

    testQThread.quit();
    testQThread.wait();

    return 0;
}

输出:

main thread id 0x1bb4
std::thread id 0x294c
std::thread finished
QThread id 0x1bd4
singleShot from std thread with qApp 0x1bb4
singleShot from QThread 0x1bb4

可以看到,qtimer执行的一直是主线程,也就是GUI线程。

本文为3YL原创,转载无需联系,但请注明来自labisart.com。

原创文章不易,如果觉得有帮助,可打赏或点击右侧广告支持:

查看打赏记录

发表评论请遵守党国法律!后台审核后方可显示!
  • 最新评论
  • 总共0条评论
  • Blog v1.1© 2024 labisart.com 版权所有 | 联系:labartwork@163.com