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