QT线程之 moveToThread() 只能用信号槽方式触发
生活随笔
收集整理的這篇文章主要介紹了
QT线程之 moveToThread() 只能用信号槽方式触发
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
qt的線程使用方法有把某個對象的函數(shù)放置線程里執(zhí)行,方法為moveToThread()
具體操作步驟為:
1、創(chuàng)建一個新的類,讓這個類從 QObject 派生
2、在這個類中添加一個公共的成員函數(shù),函數(shù)體就是我們要子線程中執(zhí)行的業(yè)務(wù)邏輯
class MyWork:public QObject { public:.......// 函數(shù)名自己指定, 叫什么都可以, 參數(shù)可以根據(jù)實際需求添加void working(); }3、在主線程中創(chuàng)建一個 QThread 對象,這就是子線程的對象
QThread* sub = new QThread;4、在主線程中創(chuàng)建工作的類對象(千萬不要指定給創(chuàng)建的對象指定父對象)
MyWork* work = new MyWork(this); // error MyWork* work = new MyWork; // ok5、將 MyWork 對象移動到創(chuàng)建的子線程對象中,需要調(diào)用 QObject 類提供的 moveToThread() 方法
// void QObject::moveToThread(QThread *targetThread); // 如果給work指定了父對象, 這個函數(shù)調(diào)用就失敗了 // 提示: QObject::moveToThread: Cannot move objects with a parent work->moveToThread(sub); // 移動到子線程中工作6、啟動子線程,調(diào)用 start(), 這時候線程啟動了,但是移動到線程中的對象并沒有工作
7、信號槽調(diào)用 MyWork 類對象的工作函數(shù),讓這個函數(shù)開始執(zhí)行,這時候是在移動到的那個子線程中運行的,需要外面的信號傳來讓MyWork執(zhí)行工作函數(shù)。
下面是一套完整的工程:
//mywork.h #ifndef MYWORK_H #define MYWORK_H#include <QObject>class MyWork : public QObject {Q_OBJECT public:explicit MyWork(QObject *parent = nullptr);// 工作函數(shù)void working();signals:void curNumber(int num);public slots: };#endif // MYWORK_H //mywork.cpp #include "mywork.h" #include <QDebug> #include <QThread>MyWork::MyWork(QObject *parent) : QObject(parent) {}void MyWork::working() {qDebug() << "當前線程對象的地址: " << QThread::currentThread();int num = 0;while(1){emit curNumber(num++);if(num == 1000){break;}QThread::usleep(1);}qDebug() << "run() 執(zhí)行完畢, 子線程退出...";} //widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QString> #include<QThread> #include "mywork.h"QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pbStart_clicked();void setNum(int num);private:Ui::Widget *ui;MyWork *work;QThread* sub; }; #endif // WIDGET_H //widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);// 創(chuàng)建線程對象sub = new QThread;// 創(chuàng)建工作的類對象// 千萬不要指定給創(chuàng)建的對象指定父對象// 如果指定了: QObject::moveToThread: Cannot move objects with a parentwork = new MyWork;// 將工作的類對象移動到創(chuàng)建的子線程對象中work->moveToThread(sub);// 啟動線程sub->start();// 讓工作的對象開始工作, 點擊開始按鈕, 開始工作connect(ui->pbStart, &QPushButton::clicked, work, &MyWork::working);// 顯示數(shù)據(jù)connect(work, &MyWork::curNumber, this, &Widget::setNum);}Widget::~Widget() {delete ui; }void Widget::on_pbStart_clicked() { // work->working(); //這個有點坑,下面重點講! }void Widget::setNum(int num) {ui->lb_time->setText(QString::number(num)); }重點來了! 最主要的問題就是子對象的working()函數(shù)到底由誰來觸發(fā)的問題
對比原因在注釋寫的很清楚了
總結(jié)
以上是生活随笔為你收集整理的QT线程之 moveToThread() 只能用信号槽方式触发的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Atiitt 前端技术点清单列表 att
- 下一篇: 程序员找不到对象是伪命题?他用大数据找对