1. 程式人生 > >Qt筆記——多線程

Qt筆記——多線程

所在 定義 動態分配空間 信號 作用 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筆記——多線程