QT之巧用對象充當信號接收者

備注:以下僅為演示不代表合理性,適合簡單任務,邏輯簡單、臨時使用,可保持代碼簡潔,對于復雜的任務應創建一個專門的類來管理信號和線程池任務.

FileScanner類繼承QObject和QRunnable,掃描指定目錄下的文件獲取文件列表,逐個發出fileFound信號;

FileHasher:繼承QObject和QRunnable,計算文件的SHA1值,發出hashResult信號;

1、使用新建臨時對象?

#include <QCoreApplication>
#include <QThreadPool>
#include "global_threadpool_example.h"int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 創建協調對象,處理信號QObject coordinator;// 啟動文件掃描任務FileScanner *scanner = new FileScanner("/path/to/your/directory"); // 替換為實際目錄QObject::connect(scanner, &FileScanner::fileFound, &coordinator, [&coordinator](const QString &filePath) {// 為每個找到的文件啟動SHA1計算任務FileHasher *hasher = new FileHasher(filePath);QObject::connect(hasher, &FileHasher::hashResult, &coordinator, [](const QString &filePath, const QString &hash) {qDebug() << "File:" << filePath << "SHA1:" << hash;});QThreadPool::globalInstance()->start(hasher);});QObject::connect(scanner, &FileScanner::finished, &coordinator, []() {qDebug() << "Scanning finished.";// 可選:等待所有任務完成QThreadPool::globalInstance()->waitForDone();qDebug() << "All tasks completed.";});// 提交掃描任務到全局線程池QThreadPool::globalInstance()->start(scanner);return app.exec();
}
  • Qt 的信號槽機制要求信號的接收者是一個 QObject 或其派生類的實例。coordinator 是一個 QObject 實例,用于連接 FileScanner 和 FileHasher 發出的信號(如 fileFound 和 hashResult)。
  • 它充當信號的“中轉站”,將任務的異步結果(例如找到的文件路徑或計算的 SHA1 值)傳遞到處理邏輯中。
  • 它可以避免在 main 函數中創建額外的類或全局對象,保持代碼簡潔。

  • coordinator 是 main 函數的局部變量,其生命周期持續到程序退出。這足以處理所有信號,因為線程池任務的信號在事件循環中處理。

2、使用QCoreApplication對象

#include <QCoreApplication>
#include <QThreadPool>
#include "global_threadpool_example.h"int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 啟動文件掃描任務FileScanner *scanner = new FileScanner("/path/to/your/directory"); // 替換為實際目錄QObject::connect(scanner, &FileScanner::fileFound, &app, [&app](const QString &filePath) {FileHasher *hasher = new FileHasher(filePath);QObject::connect(hasher, &FileHasher::hashResult, &app, [](const QString &filePath, const QString &hash) {qDebug() << "File:" << filePath << "SHA1:" << hash;});QThreadPool::globalInstance()->start(hasher);});QObject::connect(scanner, &FileScanner::finished, &app, []() {qDebug() << "Scanning finished.";QThreadPool::globalInstance()->waitForDone();qDebug() << "All tasks completed.";});// 提交掃描任務到全局線程池QThreadPool::globalInstance()->start(scanner);return app.exec();
}

QCoreApplication 是 Qt 應用程序的主對象,無需額外創建 QObject,app存在于整個程序生命周期,也可以直接用作信號槽連接的接收者,也適合信號槽邏輯簡單、臨時使用的場景。

缺點:語義上不夠清晰,因為 QCoreApplication 的主要職責是管理應用程序,而不是任務協調,如果程序中有多個模塊使用 app 處理信號,可能會導致信號槽邏輯混雜,這種方式并不推薦。

3、使用 lambda 表達式

#include <QCoreApplication>
#include <QThreadPool>
#include "global_threadpool_example.h"int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 啟動文件掃描任務FileScanner *scanner = new FileScanner("/path/to/your/directory"); // 替換為實際目錄QObject::connect(scanner, &FileScanner::fileFound, [=](const QString &filePath) {FileHasher *hasher = new FileHasher(filePath);QObject::connect(hasher, &FileHasher::hashResult, [](const QString &filePath, const QString &hash) {qDebug() << "File:" << filePath << "SHA1:" << hash;});QThreadPool::globalInstance()->start(hasher);});QObject::connect(scanner, &FileScanner::finished, []() {qDebug() << "Scanning finished.";QThreadPool::globalInstance()->waitForDone();qDebug() << "All tasks completed.";});// 提交掃描任務到全局線程池QThreadPool::globalInstance()->start(scanner);return app.exec();
}

Qt 允許在信號連接中使用 lambda 表達式直接處理邏輯,無需顯式的接收者對象。這種方式將信號處理邏輯直接嵌入 lambda 函數中。適合信號槽邏輯簡單、臨時使用的場景。

  • 代碼更簡潔,無需創建額外的 QObject,邏輯集中在 lambda 函數中,易于理解。
  • lambda 表達式無法像 QObject 那樣方便地管理多個信號槽連接(例如斷開連接),而且如果 lambda 中捕獲了變量(如 [=]),特別需要注意捕獲變量的生命周期。

4、使用靜態函數或全局函數處理信號

#include <QCoreApplication>
#include <QThreadPool>
#include "global_threadpool_example.h"// 靜態函數處理信號
static void handleFileFound(const QString &filePath) {FileHasher *hasher = new FileHasher(filePath);QObject::connect(hasher, &FileHasher::hashResult, [](const QString &filePath, const QString &hash) {qDebug() << "File:" << filePath << "SHA1:" << hash;});QThreadPool::globalInstance()->start(hasher);
}static void handleFinished() {qDebug() << "Scanning finished.";QThreadPool::globalInstance()->waitForDone();qDebug() << "All tasks completed.";
}int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 啟動文件掃描任務FileScanner *scanner = new FileScanner("/path/to/your/directory"); // 替換為實際目錄QObject::connect(scanner, &FileScanner::fileFound, handleFileFound);QObject::connect(scanner, &FileScanner::finished, handleFinished);// 提交掃描任務到全局線程池QThreadPool::globalInstance()->start(scanner);return app.exec();
}

?定義靜態函數 handleFileFound 和 handleFinished,直接連接到信號,不需要 QObject 接收者。但這種方式,靜態函數無法方便地存儲狀態(如任務列表、結果收集),不易擴展,維護性較差,僅適合信號處理邏輯非常簡單的情況。

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

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

相關文章

Transformer,多頭注意力機制 隱式學習子空間劃分

Transformer,多頭注意力機制 隱式學習子空間劃分 在Transformer中,多頭注意力機制天然支持隱式學習子空間劃分——每個注意力頭可以專注于輸入的不同方面(如語義、句法、位置關系等),從而隱式形成多個子空間。 一、核心思路:將多頭注意力視為隱式子空間 原理 Transfo…

java基礎(繼承)

什么是繼承 繼承好處 提高代碼的復用性 繼承注意事項 權限修飾符 單繼承、Object類 沖突&#xff1a; 方法重寫 擴展&#xff1a; 其實我們不想看地址&#xff0c;地址看來沒用&#xff0c;我們是用來看對象有沒有問題 重寫toString: 比如這個如果返回的是地址值&#xff0c;…

【每日渲美學】3ds Max櫥柜材質教程:廚房高光烤漆、木紋、亞克力、亞光板材渲染優化指南

在室內可視化項目中&#xff0c;廚房往往是一個集中展現材質表現力與光影質感的關鍵區域。櫥柜作為廚房空間的視覺主體&#xff0c;其材質選擇與渲染設置不僅影響整體空間的風格呈現&#xff0c;也對渲染效率提出更高要求。 本期「每日渲美學」&#xff0c;我們聚焦3ds Max環境…

Python Day34

Task&#xff1a; GPU訓練及類的call方法 1.CPU性能的查看&#xff1a;看架構代際、核心數、線程數 2.GPU性能的查看&#xff1a;看顯存、看級別、看架構代際 3.GPU訓練的方法&#xff1a;數據和模型移動到GPU device上 4.類的call方法&#xff1a;為什么定義前向傳播時可以直接…

HTTP協議版本的發展(HTTP/0.9、1.0、1.1、2、3)

目錄 HTTP協議層次圖 HTTP/0.9 例子 HTTP/1.0 Content-Type 字段 Content-Encoding 字段 例子 1.0版本存在的問題&#xff1a;短鏈接、隊頭阻塞 HTTP/1.1 Host字段 Content-Length 字段 分塊傳輸編碼 1.1版本存在的問題 HTTP/2 HTTP/2數據傳輸 2版本存在的問題…

開源 OIDC(OpenID Connect)身份提供方(IdP)、iam選型

文章目錄 開源 OIDC(OpenID Connect)身份提供方(IdP)、iam選型主流開源 OIDC(OpenID Connect)身份提供方(IdP)zitadeldexory開源 OIDC(OpenID Connect)身份提供方(IdP)、iam選型 主流開源 OIDC(OpenID Connect)身份提供方(IdP) 當前主流的**開源 OIDC(OpenI…

第三十二天打卡

作業&#xff1a;參考pdpbox官方文檔中的其他類&#xff0c;繪制相應的圖&#xff0c;任選即可 1. 安裝并導入庫 確保安裝與文檔版本一致的 pdpbox&#xff08;此處以 0.3.0 為例&#xff09;&#xff1a; bash 復制 下載 pip install pdpbox0.3.0 導入所需庫&#xff1a…

【Spring】Spring AI 核心知識(一)

1. 自定義 Advisor 實際上&#xff0c;Advisor 可以看做是 Servlet 當中的“攔截器”&#xff0c;在大模型接收到 prompt 之前進行前置攔截增強&#xff08;比如敏感詞校驗、記錄日志、鑒權&#xff09;&#xff0c;并在大模型返回響應之后進行后置攔截增強&#xff08;比如記…

中國免稅品人工智能商城:引領免稅品市場新潮流

在全球經濟一體化的時代背景下&#xff0c;免稅品市場日益繁榮。中國免稅品人工智能商城以對標洋碼頭為目標&#xff0c;積極利用人工智能的優勢&#xff0c;結合自身特點&#xff0c;全力打造成為免稅品類的示范性商業平臺&#xff0c;為消費者帶來全新的購物體驗。 一、免稅品…

LambdaQueryWrapper、MybatisPlus提供的基本接口方法、增刪改查常用的接口方法、自定義 SQL

DAY26.2 Java核心基礎 MybatisPlus提供的基本接口方法 分頁查詢 導入依賴springboot整合Mybatis-plus <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version&g…

謝飛機的Java面試奇遇:AIO、BIO、NIO與Netty深度解析

謝飛機的Java面試奇遇&#xff1a;AIO、BIO、NIO與Netty深度解析 在一場充滿笑料的面試中&#xff0c;謝飛機面對嚴肅的面試官&#xff0c;從Java IO的基本概念開始&#xff0c;逐步展開對AIO、BIO、NIO的理解&#xff0c;以及Netty的高級用法。 面試現場&#xff1a;第一輪&…

三、Docker目錄掛載、卷映射、網絡

目錄掛載 如果主機目錄為空&#xff0c;則容器內也為空 -v表示目錄掛載 冒號前面的是主機上的目錄&#xff0c;冒號后面的是docker容器里面的地址 修改主機上的文件&#xff0c;發現docker容器里面的內容也隨之改變。 同樣修改docker容器里面的內容&#xff0c;主機上的文件…

Linux的學習_基礎4_指令的實踐

目錄&#xff1a; 一、常用功能 二、指令實踐 1、tail命令 2、ls命令 3、ps、kill命令 4、cd、vim命令 5、root權限與用戶權限的轉換 6、獲取網卡信息 7、sudo chmodx 8、更換到別的目錄 9、獲取文件的內容 10、lsblk 查看塊設備和文件系統信息 11、man指令與指令…

深入解析Spring Boot與Redis集成:高效緩存與性能優化

深入解析Spring Boot與Redis集成&#xff1a;高效緩存與性能優化 引言 在現代Web應用中&#xff0c;緩存技術是提升系統性能的重要手段之一。Redis作為一種高性能的內存數據庫&#xff0c;廣泛應用于緩存、會話管理和消息隊列等場景。本文將詳細介紹如何在Spring Boot項目中集…

基于微信小程序的漫展系統的設計與實現

博主介紹&#xff1a;java高級開發&#xff0c;從事互聯網行業六年&#xff0c;熟悉各種主流語言&#xff0c;精通java、python、php、爬蟲、web開發&#xff0c;已經做了六年的畢業設計程序開發&#xff0c;開發過上千套畢業設計程序&#xff0c;沒有什么華麗的語言&#xff0…

藍橋杯電子賽_零基礎利用按鍵實現不同數字的顯現

目錄 一、前提 按鍵的原理圖 二、代碼配置 bsp_key.c文件 疑問 main.c文件 main.c文件的詳細講解 功能實現 注意事項 一、前提 按鍵這一板塊主要是以記憶為主&#xff0c;我直接給大家講解代碼去實現我要配置的功能。本次我要做的項目是板子上的按鍵有S4~S19&#xff…

Python常用高階函數全面解析:通俗易懂的指南

Python常用高階函數全面解析&#xff1a;通俗易懂的指南 一、什么是高階函數&#xff1f; 高階函數(Higher-order Function)是指能夠接受其他函數作為參數&#xff0c;或者將函數作為返回值的函數。在Python中&#xff0c;函數是一等公民&#xff0c;可以像普通變量一樣傳遞和…

Flume之選擇器:復制和多路復用(比喻化理解

Flume 的選擇器決定了Source 如何將數據分發到多個 Channel。這就像 “快遞員如何分配包裹到不同的運輸通道”&#xff0c;有兩種策略&#xff1a;復制和多路復用。 一、復制&#xff08;Replicating Selector&#xff09;&#xff1a;每個 Channel 都送一份 核心邏輯 將同一…

yolov5 安卓運行

參考博客&#xff1a; 通過Android Studio 將yolov5部署到手機端(新手最新適用版)_怎么將yolo部署手機-CSDN博客 總體跟隨參考博客走是沒問題&#xff0c;有些細節需要注意&#xff1a; 1 jdk 版本選擇&#xff0c;jdk需要17&#xff0c;新版的Android Studio 選擇jdk版本方式…

day021-定時任務

文章目錄 1. cron1.1 檢查是否安裝1.2 檢查是否開機自啟動1.3 配置文件與相關命令1.4 配置文件格式 2. 案例2.1 同步時間2.2 定時備份/etc和/var/log目錄2.3 定時巡檢腳本 3. 練習三劍客過濾3.1 去重統計ip數量3.2 去重統計第7列 用戶訪問的url的數量3.3 去重統計第9列 狀態碼與…