QT多线程之:moveToThread
不能在另外的線程直接delete一個QObject對象,相反,你需要調用QObject::deleteLater()函數,這個函數會給對象所在線程發送一個刪除的事件。
QObject的線程依附性是可以改變的,方法是調用QObject::moveToThread()函數。該函數會改變一個對象及其所有子對象的線程依附性。
由于QObject不是線程安全的,所以我們只能在該對象所在線程上調用這個函數。也就是說,我們只能在對象所在線程將這個對象移動到另外的線程,不能在另外的線程改變對象的線程依附性。
還有一點是,Qt 要求QObject的所有子對象都必須和其父對象在同一線程。這意味著:
- 不能對有父對象(parent 屬性)的對象使用QObject::moveToThread()函數
- 不能在QThread中以這個QThread本身作為父對象創建對象,例如下面的代碼片段:這是因為QThread對象所依附的線程是創建它的那個線程,而不是它所代表的線程。
參考:QT 學習之路 2(74):線程和 QOBJECT
class Test : public QObject {Q_OBJECT public:Q_INVOKABLE void show(int i) {qDebug()<<"show "<<i<<" in thread: "<<QThread::currentThread();} };
需要用Q_INVOKABLE聲明,invokeMethod才能調用,否則會找不到show這個接口。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);auto t = new Test;auto thread = new QThread;thread->start();int i = 0;qDebug()<<"main thread: "<<QThread::currentThread();t->show(i++); // 0QMetaObject::invokeMethod(t, "show", Qt::DirectConnection, Q_ARG(int, i++)); // 1connect(this, &MainWindow::test, t, &Test::show);emit test(i++); // 2disconnect(this, &MainWindow::test, t, &Test::show);t->moveToThread(thread);qDebug()<<"after move to thread: "<<QThread::currentThread();t->show(i++); // 3QMetaObject::invokeMethod(t, "show", Qt::DirectConnection, Q_ARG(int, i++)); // 4QMetaObject::invokeMethod(t, "show", Qt::QueuedConnection, Q_ARG(int, i++)); // 5connect(this, &MainWindow::test, t, &Test::show, Qt::DirectConnection);emit test(i++); // 6disconnect(this, &MainWindow::test, t, &Test::show);connect(this, &MainWindow::test, t, &Test::show);emit test(i++); // 7disconnect(this, &MainWindow::test, t, &Test::show); }
只有在線程啟動后,并且通過信號槽和invokeMethod調用,且是隊列的方式,才能讓QOject子對象的show函數跑在子線程中。
并非是將a實例相關的所有的工作“移動”到了m_thread線程,而是將所有a實例相關的事件托管到m_thread線程執行。換句話說,就是通過信號槽connect或者invokeMethod觸發a實例中槽函數產生的事件,將會被放置到m_thread線程中執行。
參考:[moveToThread實現多線程操作的理解(https://blog.csdn.net/yzt629/article/details/105429367)
Q_INVOKABLE與invokeMethod用法全解
總結
以上是生活随笔為你收集整理的QT多线程之:moveToThread的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 私有网段IP地址的划分
- 下一篇: 微信小程序--火车票查询