1. 程式人生 > >Qt的QThread多執行緒使用

Qt的QThread多執行緒使用

QThread簡介

最近開發某C++的AI專案,需要用到介面,為了計算過程不阻塞介面,需要使用多執行緒,在這裡學習下Qt自帶的多執行緒操作。

QThread是一個與平臺無關的執行緒類,用於多執行緒的程式設計。具體可以在文件中中索引QThread關鍵字。實際開發中,一般繼承這個類,然後執行類的run函式,這也是一個槽,注意接受一個整型資料。耗時的操作放在run函式中執行。

實際應用

下面給出一個多執行緒的模擬檔案傳輸的例子。定義一個MyThread類,繼承自QThread,在run函式中模擬一次傳輸。主介面顯示進度。 執行效果: 初始化:

傳輸過程: 傳輸完畢:

該程式碼沒有給出介面設計的,只要自己從中拖拽進去一個QPushButton、QProgressBar和QLabel即可,都是使用的預設名稱。

自定義的類標頭檔案

/*
* mythread.h
*/
#ifndef MYTHERAD_H
#define MYTHERAD_H

#include <QThread>
#include <QString>

class MyTherad : public QThread
{
    Q_OBJECT
public:
    MyTherad();
    void run() override;
    void startThread();
    unsigned long t;        // 間斷時間
signals:
    void resultReady
(const QString &s); void sendValue(int v); // 傳送資料用的 }; #endif // MYTHERAD_H

實現檔案

/*
* mythread.cpp
*/
#include "mytherad.h"

MyTherad::MyTherad()
{
    t=100;  // 預設睡眠1000毫秒
}

void MyTherad::run(){
    QString result=tr("資料傳輸完畢!");
    for(int i=0;i<=100;++i){
        msleep(t);
        sendValue(i)
; // 向外界傳送資料 } emit resultReady(result); } void MyTherad::startThread(){ run(); }

Widget視窗的標頭檔案

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QProgressBar>
#include <QLabel>
#include "mytherad.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

public slots:
    void setText();

private:
    Ui::Widget *ui;

    MyTherad myThread;
};

#endif // WIDGET_H

Widget視窗的實現檔案

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 重新顯示文字,注意槽的連線順序
    QObject::connect(ui->pushButton,&QPushButton::clicked,this,&Widget::setText);
    // 啟動執行緒
    QObject::connect(ui->pushButton,&QPushButton::clicked,&myThread,&MyTherad::startThread);
    // 顯示資料
    QObject::connect(&myThread,&MyTherad::sendValue,ui->progressBar,&QProgressBar::setValue);
    // 追加資料內容
    QObject::connect(&myThread,&MyTherad::resultReady,ui->label,&QLabel::setText);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::setText(){
    ui->label->setText("等待資料傳輸........");
}