QThread笔记(一)

发布于:2025-02-10 ⋅ 阅读:(23) ⋅ 点赞:(0)

QThread官方文档

It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). This means that all of QThread’s queued slots and invoked methods will execute in the old thread. Thus, a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.

Unlike queued slots or invoked methods, methods called directly on the QThread object will execute in the thread that calls the method. When subclassing QThread, keep in mind that the constructor executes in the old thread while run() executes in the new thread. If a member variable is accessed from both functions, then the variable is accessed from two different threads. Check that it is safe to do so.

知识盲点

  • 实例化QThread的类中的槽函数或invoked方法调用将在之前的旧线程中执行
  • 如果要在新的线程中执行,则需要使用worker-object方案(moveToThread())

代码验证

  • 实例化QThread验证

    • 代码实现
    SubThr::SubThr(QObject *parent)
        : QThread(parent)
    {
        qDebug() << "SubThr::TestThr() " << QThread::currentThreadId();
    }
    
    SubThr::~SubThr()
    {}
    
    void SubThr::slot1()
    {
        qDebug() << "SubThr::slot1() " << QThread::currentThreadId();
    }
    
    void SubThr::run()
    {
        qDebug() << "SubThr::run() " << QThread::currentThreadId();
        while (true)
        {
            QThread::msleep(10000);
        }
    }
    
    ...
    
    SubThr* subThr = new SubThr();
    subThr->start();
    
    QTimer::singleShot(3000, [=]() {
        QMetaObject::invokeMethod(subThr, "slot1");
    });
    
    
    • 输出
    SubThr::TestThr()  0x8270
    SubThr::run()  0x8998
    SubThr::slot1()  0x8270
    
  • worker-object验证

    • 代码实现
    WorkObj::WorkObj(QObject *parent)
    : QObject(parent)
    {
        qDebug() << "WorkObj::WorkObj() " << QThread::currentThreadId();
    }
    
    WorkObj::~WorkObj()
    {}
    
    void WorkObj::slot1()
    {
        qDebug() << "WorkObj::slot1() " << QThread::currentThreadId();
    }
    
    ...
    
    WorkObj* wobj = new WorkObj();
    wobj->moveToThread(&m_thr);
    connect(&m_thr, &QThread::started, [this]() {
    	qDebug() << "QThread:: " << m_thr.currentThreadId();
    });
    m_thr.start();
    
    QTimer::singleShot(3000, [=]() {
    	QMetaObject::invokeMethod(wobj, "slot1");
    });
    
    
    • 输出
    WorkObj::WorkObj()  0x7530
    QThread::  0x3fb8
    WorkObj::slot1()  0x3fb8
    

网站公告

今日签到

点亮在社区的每一天
去签到