Qt---線程使用

   換了新部門,對FPGA底層的使用不多,更多的是c和c++,於是開始了Qt界面的學習,在練習c和c++的同時,學習做界面,很多測試就不需要依賴別人。

 Qt中的QThread類提供了平臺無關的線程。一個QThread代表了一個在應用程序中可以獨立控制的線程,它與進程中的其他線程分享數據,但是獨立執行的。相對於一般的程序都是從main()函數開始執行,QThread從run()函數開始執行。默認的,run()通過調用exec()來開啓事件循環並在線程內運行一個Qt事件循環。要創建一個線程,需要子類化QThread並且重新實現run()函數。

需要注意的是:

QThread只有run函數是在新線程裏的,其他所有函數都在QThread生成的線程裏
如果QThread是在ui所在的線程裏生成,那麼QThread的其他非run函數都是和ui線程一樣的,所以QThread的繼承類的其他函數儘量別要有太耗時的操作,要確保所有耗時的操作都在run函數裏。
在UI線程下調用QThread的非run函數(其實也不應該直接調用run函數,而應該使用start函數),和執行普通函數無區別,這時,如果這個函數要對QThread的某個變量進行變更,而這個變量在run函數裏也會被用到,這時就需要注意加鎖的問題,因爲可能這個變量前幾毫秒剛剛在run中調用,再調用時已經被另外的線程修改了。

我的理解:習慣了FPGA底層的並行處理,一時有些難以理解線程的處理。其實線程:通過並行處理方式,提高代碼的響應速度,處理方法類似於底層的流水線操作。例如我需要接收外部數據並顯示在界面上,假設外部每3秒發送一次數據,每次接收數據需要1.5秒,數據更新顯示需要2秒,如果串行處理所花費時間爲3.5秒,那麼數據會丟失,如果並行處理,那麼每次處理時間爲2秒。

實例使用:

新建工程,main函數使用默認代碼,添加線程類代碼和頭文件:
mthread.cpp:

#include "mthread.h"
#include <QDebug>

MyThread::MyThread(QObject *parent) :
    QThread(parent)
{
    stopped = false;
}
//run()函數的定義:
void MyThread::run()
{

    while (!stopped) 
	{   
        qDebug() << QString("in MyThread: %1").arg(thr_num);
        msleep(1000);    

	}
    stopped = false;
}

void MyThread::stop()    
{     
	stopped = true;   
}

頭文件內容:

#include <QThread>

class MyThread : public QThread
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = 0);
    void stop();

    int thr_num;

protected:
    void run();
private:
    volatile bool stopped;
};

mainwindow.h修改:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QTimer>
#include "mthread.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void dealtimeout();

private:
    Ui::MainWindow *ui;
    MyThread *thread;
     MyThread *thread2;
     QTimer *timer;
};

#endif // MAINWINDOW_H

mainwindow.cpp修改如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    thread = new MyThread(this);
    thread->thr_num=1;

    thread2 = new MyThread(this);
    thread2->thr_num=2;


    timer = new QTimer(this);
    timer->start(100);
    connect(timer,&QTimer::timeout,this,&MainWindow::dealtimeout);
}

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

void MainWindow::on_pushButton_clicked()
{
    thread->start();
    thread2->start();
    ui->pushButton->setEnabled(false);
    ui->pushButton_2->setEnabled(true);

}

void MainWindow::on_pushButton_2_clicked()
{
    thread->stop();
    thread2->stop();
    ui->pushButton->setEnabled(true);
    ui->pushButton_2->setEnabled(false);
}

void MainWindow::dealtimeout()//更新LCD顯示器的數字
{
    static int time = 0;
    ui->lcdNumber->display(time);
    time++;
}

運行結果如下:主線程在定時器修改LCD,兩個子線程在打印,子線程沒有運行順序之分。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章