QT 多線程 QThread

繼承QThread的線程

繼承 QThread 是創建線程的一個普通方法。其中創建的線程只有 run() 方法在線程里的。其他類內定義的方法都在主線程內。
通過上面的圖我們可以看到,主線程內有很多方法在主線程內,但是子線程,只有 run() 方法是在子線程里的 run() 方法是繼承于 QThread 類的方法,用戶需要重寫這個方法,一般是把耗時的操作寫在這個 run() 方法里面。
QThread 類繼承線程,然后在 MainWindow 類里使用。通過點擊一個按鈕開啟線程。當線程執行完成時,會發送 resultReady(const QString &s) 信號給主線程,代碼如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QThread>
#include <QDebug>
#include <QPushButton>class WorkerThread;class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:QPushButton *pushButton;WorkerThread *workThread;private slots:void handleResults(const QString &result);void pushButtonClicked();
};class WorkerThread : public QThread
{Q_OBJECTpublic:WorkerThread(QWidget *parent = nullptr){Q_UNUSED(parent);}void run() override {QString result = "Thread Start";/** Timerout*/sleep(2);emit resultReady(result);}signals:void resultReady(const QString &s);
};
#endif // MAINWINDOW_H
#include "mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{this->setGeometry(0,0,800,480);pushButton = new QPushButton(this);workThread = new WorkerThread(this);pushButton->resize(100,40);pushButton->setText("Start Thread");/* 信號槽連接 */connect(workThread, &WorkerThread::resultReady,this, &MainWindow::handleResults);connect(pushButton, &QPushButton::clicked,this, &MainWindow::pushButtonClicked);
}MainWindow::~MainWindow()
{workThread->quit();if(workThread->wait(2000)){qDebug() << "Thread end" << endl;}
}void MainWindow::handleResults(const QString &result)
{qDebug() << result << endl;
}void MainWindow::pushButtonClicked()
{if (!workThread->isRunning())workThread->start();
}

上述代碼很簡單,相信都能看懂。
主窗口構造函數:當創建 MainWindow 對象時,構造函數設置窗口尺寸,初始化按鈕和工作線程,并連接信號槽。
按鈕點擊事件:當用戶點擊按鈕時,調用 pushButtonClicked 槽函數,啟動線程。
線程執行:線程開始運行,暫停2秒,然后發出 resultReady 信號。
結果處理:信號槽機制確保 handleResults 槽函數被調用,輸出線程結果。
主窗口析構函數:在銷毀 MainWindow 對象時,確保線程被正確終止并釋放資源。

效果:

點擊開啟線程按鈕后,延時 2s 后, Qt Creator 的應用程序輸出窗口打印出“線程開啟成功”。
2s 內多次點擊按鈕則不會重復開啟線程,因為線程在這 2s 內還在運行。同時我們可以看到
點擊按鈕沒卡頓現象。因為這個延時操作是在我們創建的線程里運行的,而 pushButton 是在主
線程里的,通過點擊按鈕控制子線程的運行。
當關閉程序后,子線程將在主線程的析構函數里退出。注意線程使用 wait() 方法,這里等
2s ,因為我們開啟的線和是延時 2s 就完成了。如果是實際的操作,請根據 CPU 的處理能力,
給一個適合的延時,阻塞等待線程完成后,就會自動退出并打印“線程已經結束”。

繼承QObject的線程

#include "mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{this->setGeometry(0,0,800,480);pushButton1 = new QPushButton(this);pushButton2 = new QPushButton(this);pushButton1->setGeometry(300, 200, 80, 40);pushButton2->setGeometry(400, 200, 80, 40);pushButton1->setText(" Start Thread ");pushButton2->setText(" failed Thread ");worker = new Worker;worker->moveToThread(&workerThread);/* 線程完成銷毀對象 */connect(&workerThread, SIGNAL(finished()),worker, SLOT(deleteLater()));connect(&workerThread, SIGNAL(finished()),&workerThread, SLOT(deleteLater()));/* 發送開始工作的信號,開始工作 */connect(this, SIGNAL(startWork(QString)),worker, SLOT(doWork1(QString)));/* 接收到 worker 發送過來的信號 */connect(worker, SIGNAL(resultReady(QString)),this, SLOT(handleResults(QString)));/* 點擊按鈕開始線程 */connect(pushButton1, SIGNAL(clicked()),this, SLOT(pushButton1Clicked()));/* 點擊按鈕打斷線程 */connect(pushButton2, SIGNAL(clicked()),this, SLOT(pushButton2Clicked()));
}MainWindow::~MainWindow()
{worker->stopwork();workerThread.quit();if(workerThread.wait(2000)){qDebug() << "Thread end" << endl;}
}void MainWindow::handleResults(const QString &result)
{qDebug() << result << endl;
}void MainWindow::pushButton1Clicked()
{const QString str = "";if (!workerThread.isRunning())workerThread.start();emit this->startWork(str);
}void MainWindow::pushButton2Clicked()
{if(workerThread.isRunning()){worker->stopwork();}
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QThread>
#include <QDebug>
#include <QPushButton>
#include <QMutexLocker>
#include <QMutex>class Worker;class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:QPushButton *pushButton1;QPushButton *pushButton2;QThread workerThread;Worker *worker;private slots:void handleResults(const QString &result);void pushButton1Clicked();void pushButton2Clicked();signals:void startWork(const QString &);
};class Worker : public QThread
{Q_OBJECTprivate:QMutex lock;bool isCanRun;public slots:void doWork1(const QString &parameter){isCanRun = true;while(1){{QMutexLocker locker(&lock);if(!isCanRun){break;}}QThread::sleep(2);emit resultReady(parameter + " dowork1 thread ");}emit resultReady("stop work1 thread");}public:void stopwork(){qDebug() << "thread failed" << endl;QMutexLocker locker(&lock);isCanRun = false;}signals:void resultReady(const QString &result);
};
#endif // MAINWINDOW_H

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/44490.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/44490.shtml
英文地址,請注明出處:http://en.pswp.cn/web/44490.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于STM32設計的藥品柜溫濕度監測系統(華為云IOT)(184)

基于STM32設計的藥品柜溫濕度監測系統(華為云IOT)(184) 文章目錄 一、前言1.1 項目介紹【1】項目功能介紹【2】整體需求總結【3】項目硬件模塊組成1.2 設計思路【1】整體設計思路【2】ESP8266工作模式配置【3】華為云IOT手機APP界面開發思路1.3 項目開發背景【1】選題的意義【2…

R語言學習筆記6-數據框

R語言學習筆記6-數據框 數據框(DataFrame)介紹數據框用途創建數據框從矩陣創建數據框索引和切片添加和修改列數據框的預處理數據框的排序數據框的合并與拆分數據框的計算與匯總數據框的篩選處理缺失值應用函數處理數據重塑數據框使用 dplyr 進行數據框的管道操作數據框的時間序…

使用 WebSocket 進行實時數據傳輸

以下是使用 WebSocket 進行實時數據傳輸的一般步驟&#xff1a; 一、前端部分 &#xff08;一&#xff09;創建 WebSocket 連接 const socket new WebSocket(ws://your-server-url); 在上述代碼中&#xff0c;將 ws://your-server-url 替換為您實際的服務器 WebSocket 地…

SvANet:微小醫學目標分割網絡,增強早期疾病檢測

SvANet&#xff1a;微小醫學目標分割網絡&#xff0c;增強早期疾病檢測 提出背景前人工作醫學對象分割微小醫學對象分割注意力機制 SvANet 結構圖SvANet 解法拆解解法邏輯鏈 論文&#xff1a;SvANet: A Scale-variant Attention-based Network for Small Medical Object Segmen…

【JAVA poi-tl-ext 富文本轉word】

富文本轉word 環境使用poi-tl-ext的原因富文本轉word代碼 環境 jdk 1.8 <dependency><groupId>io.github.draco1023</groupId><artifactId>poi-tl-ext</artifactId><version>0.4.16</version> </dependency>poi-tl-ext已經包…

可靈重大升級!新增Web端上線、首尾幀控制、單次生成視頻時長增加至10s!

快手視頻生成大模型“可靈”&#xff08;Kling&#xff09;&#xff0c;作為全球首個真正用戶可用的視頻生成大模型&#xff0c;自面世以來&#xff0c;憑借其無與倫比的視頻生成效果&#xff0c;在全球范圍內贏得了用戶的熱烈追捧與高度評價。截至目前&#xff0c;申請體驗其內…

修正版頭像上傳組件

修正版頭像上傳組件 文章說明核心源碼展示運行效果展示源碼下載 文章說明 在頭像剪切上傳一文中&#xff0c;我采用div做裁剪效果&#xff0c;感覺會有一些小問題&#xff0c;在昨天基于canvas繪制的功能中改進了一版&#xff0c;讓代碼變得更簡潔&#xff0c;而且通用性相對高…

永恒之藍:一場網絡風暴的啟示

引言 在網絡安全的漫長歷史中&#xff0c;“永恒之藍”&#xff08;EternalBlue&#xff09;是一個不可忽視的里程碑事件。它不僅揭示了網絡世界的脆弱性&#xff0c;還促使全球范圍內對網絡安全的重視達到了前所未有的高度。本文將深入探討“永恒之藍”漏洞的起源、影響及其對…

【WebGIS】從設計層面設計系統

本項目在通過現代信息技術手段&#xff0c;對古村古鎮進行多方位、多角度的數字化記錄、展示與傳播&#xff0c;實現文化遺產的數字化保護、活化利用與共享。項目內容主要包括&#xff1a;1&#xff09;古村古鎮數據庫的建立&#xff1a;通過多種渠道收集古村古鎮的各類信息&am…

期貨量化交易客戶端開源教學第八節——TCP通信服務類

private FReciveStr: AnsiString; {接收到的數據} IsConErr: Boolean; {網絡連接是否失敗} FSocket_LB: Integer; {TCP連接類別,0為交易,1為行情,2為查詢} FRetryCount: Integer; {網絡連接重試次數} FLoginErrEvent: TLoginErrEvent; {…

如何從 PDF 中刪除背景

您是否曾經收到過充滿分散注意力背景的掃描 PDF 文檔&#xff1f;也許是帶有繁忙水印的舊收據或背景光線不均勻的掃描文檔。雖然這些背景可能看起來沒什么大不了的&#xff0c;但它們會使您的工作空間變得混亂&#xff0c;并使您難以專注于重要信息。輕松刪除這些不需要的元素并…

短視頻SEO矩陣系統:源碼開發與部署全攻略

在數字化時代&#xff0c;短視頻已成為人們獲取信息、娛樂休閑的重要方式。隨著短視頻平臺的興起&#xff0c;如何讓自己的內容在眾多視頻中脫穎而出&#xff0c;成為每個創作者和內容運營者關注的焦點。本文將為您深入解析短視頻SEO矩陣系統的源碼開發與部署&#xff0c;助您在…

MT6825磁編碼IC在智能雙旋機器人中的應用

MT6825磁編碼IC在智能雙旋機器人中的應用&#xff0c;無疑為這一領域的創新和發展注入了新的活力。作為一款高性能的磁性位置傳感器&#xff0c;MT6825以其獨特的優勢&#xff0c;在智能雙旋機器人的運動控制、定位精度以及系統穩定性等方面發揮了關鍵作用。 www.abitions.com …

django ninja get not allowed 能用 put delete

遇到一個奇怪的問題&#xff0c;django-ninja 編寫的 get post 方法不能使用 # 獲取Material router.get(/material, responseList[MaterialSchemaOut]) paginate(MyPagination) def list_material(request, filters: Filters Query(...)):qs retrieve(request, Material, f…

Midjourney v6.5 可能會在“7月底”發布,并改進了真實感和皮膚紋理

Midjourney v6.5即將發布&#xff0c;這一更新將大幅提升圖像的真實感和皮膚紋理&#xff0c;為用戶帶來更逼真的視覺體驗。首席執行官David Holz在電話會議中宣布&#xff0c;新版本將提高圖像清晰度&#xff0c;特別是在手部和皮膚細節上&#xff0c;同時改進Web應用程序和個…

ABAP調用BAPI時COMMIT WORK AND WAIT未按照預期同步提交問題分析

背景&#xff1a; 在做ABAP開發時&#xff0c;經常會有連續調用BAPI的需求&#xff0c;比如先創建銷售訂單&#xff0c;再依據銷售訂單創建交貨單&#xff0c;再對交貨單進行過賬等類似的一連串調用&#xff0c;這種類似的場景往往需要前一步操作的數據完全寫入數據庫才能進行…

編譯打包自己的云手機(redroid)鏡像

前言 香橙派上跑云手機可以看之前的文章&#xff1a; 香橙派5plus上跑云手機方案一 redroid(帶硬件加速)香橙派5plus上跑云手機方案二 waydroid 還有一個cuttlefish方案沒說&#xff0c;后面再研究&#xff0c;cuttlefish的優勢在于可以自定義內核且selinux是開啟的&#xf…

vue3下載base64文件

如果后端明確告訴你返回的是base64&#xff0c;那請求頭就不用帶responseType: “blob”,和普通的接口一樣發送就行 await materialsFile({ id: proxy.$route.query.id }).then((res) > {if (res) {// atob先解碼base64數據const raw window.atob(res.data);// 獲取解碼后…

vscode 遠程開發

目錄 vscode 遠程連接 選擇 Python 環境 vscode 遠程連接 按 CtrlShiftP 打開命令面板。輸入并選擇 Remote-SSH: Open SSH Configuration File...。選擇 ~/.ssh/config 文件&#xff08;如果有多個選項&#xff09;。在打開的文件中添加或修改你的 SSH 配置。 這個可以右鍵…

Jupyter Notebook基礎:用IPython實現動態編程

Jupyter Notebook基礎&#xff1a;用IPython實現動態編程 1. 引言 Jupyter Notebook是一個基于Web的交互式計算環境&#xff0c;允許用戶創建和共享包含實時代碼、方程式、可視化和文本敘述的文檔。它廣泛應用于數據清洗與轉換、數值模擬、統計建模、機器學習以及其他數據科學…