Qt筆記——多線程
阿新 • • 發佈:2018-04-15
所在 定義 動態分配空間 信號 作用 btn ots qdebug set
這個例子是,點擊開始按鈕,數字累加,點擊停止按鈕,數字不動。
1,新建一個類,裏面是子線程的內容
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include "mythread.h" #include <QDebug> namespace Ui { class MyWidget; } class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = 0);~MyWidget(); void dealSignal(); void dealClose(); signals: void startThread();//啟動子線程 private slots: void on_startBtn_clicked(); void on_stopBtn_clicked(); private: Ui::MyWidget *ui; MyThread *myT; QThread *thread; }; #endif // MYWIDGET_H
#include "mywidget.h" #include"ui_mywidget.h" #include <QThread> MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); //動態分配空間,不能指定父對象 myT = new MyThread; //創建子線程 thread = new QThread(this); //把自定義線程加入到子線程中 myT->moveToThread(thread); connect(myT,&MyThread::mySignal,this,&MyWidget::dealSignal); qDebug()<<"主線程號: "<<QThread::currentThread(); connect(this,&MyWidget::startThread,myT,&MyThread::myTimeout); connect(this,&MyWidget::destroyed,this,&MyWidget::dealClose); //線程處理函數內部,不允許操作圖形界面 //connect()第五個參數的作用,連接方式:默認,隊列,直接 //多線程才有意義 //默認的時候,如果是多線程,默認使用隊列,如果是單線程,默認是用直接方式 //隊列:槽函數所在線程和接受者一樣 //直接:槽函數所在線程和發送者一樣 } void MyWidget::dealClose() { on_stopBtn_clicked(); delete myT; } void MyWidget::dealSignal() { static int i = 0; i++; ui->lcdNumber->display(i); } MyWidget::~MyWidget() { delete ui; } void MyWidget::on_startBtn_clicked() { if(thread->isRunning() == true) { return; } //啟動線程,但是沒有啟動線程 thread->start(); myT->setFlag(false); //不能直接調用線程處理函數,直接調用導致線程處理函數和主線程在同一個線程 //myT->myTimeout(); //錯的 //只能通過 signal-slot方式調用 emit startThread(); } void MyWidget::on_stopBtn_clicked() { if(thread->isRunning() == false) { return; } myT->setFlag(true); thread->quit(); thread->wait(); }
2,主線程中創建QTread 對象,然後將子線程類通過moveToThread()中來
並且不直接調用子程序(子線程),通過主程序發出一個信號,然後子程序接受到信號,開始運行
#ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include "mythread.h" #include <QDebug> namespace Ui { class MyWidget; } class MyWidget : public QWidget { Q_OBJECT public: explicit MyWidget(QWidget *parent = 0); ~MyWidget(); void dealSignal(); void dealClose(); signals: void startThread();//啟動子線程 private slots: void on_startBtn_clicked(); void on_stopBtn_clicked(); private: Ui::MyWidget *ui; MyThread *myT; QThread *thread; }; #endif // MYWIDGET_H
#include "mywidget.h" #include "ui_mywidget.h" #include <QThread> MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget) { ui->setupUi(this); //動態分配空間,不能指定父對象 myT = new MyThread; //創建子線程 thread = new QThread(this); //把自定義線程加入到子線程中 myT->moveToThread(thread); connect(myT,&MyThread::mySignal,this,&MyWidget::dealSignal); qDebug()<<"主線程號: "<<QThread::currentThread(); connect(this,&MyWidget::startThread,myT,&MyThread::myTimeout); connect(this,&MyWidget::destroyed,this,&MyWidget::dealClose); //線程處理函數內部,不允許操作圖形界面 //connect()第五個參數的作用,連接方式:默認,隊列,直接 //多線程才有意義 //默認的時候,如果是多線程,默認使用隊列,如果是單線程,默認是用直接方式 //隊列:槽函數所在線程和接受者一樣 //直接:槽函數所在線程和發送者一樣 } void MyWidget::dealClose() { on_stopBtn_clicked(); delete myT; } void MyWidget::dealSignal() { static int i = 0; i++; ui->lcdNumber->display(i); } MyWidget::~MyWidget() { delete ui; } void MyWidget::on_startBtn_clicked() { if(thread->isRunning() == true) { return; } //啟動線程,但是沒有啟動線程 thread->start(); myT->setFlag(false); //不能直接調用線程處理函數,直接調用導致線程處理函數和主線程在同一個線程 //myT->myTimeout(); //錯的 //只能通過 signal-slot方式調用 emit startThread(); } void MyWidget::on_stopBtn_clicked() { if(thread->isRunning() == false) { return; } myT->setFlag(true); thread->quit(); thread->wait(); }
Qt筆記——多線程