Qt事件循環機制

??????? 受事件循環機制影響,按鈕的樣式表改變了可能不會立即刷新。

??????? 需要使用 update()repaint()

??? 或者調用 QApplication::processEvents() 強制處理所有待處理的事件,從而確保界面更新。

????????在 Qt 中,事件循環(Event Loop)是應用程序的核心機制,負責處理各種事件(如用戶輸入、窗口消息、定時器事件等),并將其分發給相應的對象進行處理。事件循環運行在主線程(通常稱為 GUI 線程)中,確保應用程序的界面響應用戶操作并保持流暢運行。

????????以下是 Qt 事件循環的工作原理和相關機制的詳細解釋:


1. 事件循環的定義

事件循環是一個無限循環,它不斷地從事件隊列(Event Queue)中取出事件,并將這些事件分發給相應的對象進行處理。事件循環的主要作用是確保應用程序能夠及時響應各種事件,從而保持界面的交互性和響應性。


2. 事件的來源

事件可以來自多種來源,包括但不限于:

  • 用戶輸入:如鼠標點擊、鍵盤輸入等。

  • 系統消息:如窗口大小改變、窗口關閉等。

  • 定時器事件:通過 QTimerQElapsedTimer 觸發的事件。

  • 網絡事件:如網絡連接狀態變化、數據接收等。

  • 自定義事件:開發者可以通過 QEvent 的派生類創建自定義事件。


3. 事件隊列

事件隊列是一個先進先出(FIFO)的隊列,用于存儲待處理的事件。當事件發生時,事件被放入事件隊列中,等待事件循環處理。事件隊列的管理由 Qt 的事件系統自動完成,開發者通常不需要直接操作事件隊列。


4. 事件循環的工作流程

事件循環的工作流程可以概括為以下步驟:

  1. 獲取事件

    • 事件循環從事件隊列中取出一個事件。

    • 如果事件隊列為空,事件循環會進入等待狀態,直到有新的事件到來。

  2. 分發事件

    • 事件循環將取出的事件分發給相應的對象(通常是窗口或控件)。

    • 分發過程通過調用對象的 event() 方法完成。

  3. 處理事件

    • 對象接收到事件后,會根據事件類型調用相應的事件處理函數(如 mousePressEventkeyPressEvent 等)。

    • 如果對象沒有處理事件,事件會繼續向上冒泡,直到被父對象或默認處理程序處理。

  4. 返回事件循環

    • 事件處理完成后,控制權返回到事件循環,事件循環繼續處理下一個事件。


5. 事件循環的啟動和停止

  • 啟動事件循環

    • 在 Qt 應用程序中,事件循環通常在 main() 函數中通過調用 QApplication::exec() 啟動。

    • QApplication::exec() 是一個阻塞調用,它會啟動事件循環并進入無限循環,直到應用程序退出。

  • int main(int argc, char* argv[]) {QApplication app(argc, argv);MainWindow mainWindow;mainWindow.show();return app.exec();  // 啟動事件循環
    }
  • 停止事件循環

    • 事件循環可以通過調用 QApplication::exit()QCoreApplication::quit() 停止。

    • 這些方法會退出事件循環,導致 QApplication::exec() 返回,應用程序隨后退出。

  • app.exit();  // 停止事件循環

6. 事件循環的嵌套

????????在某些情況下,可能需要在事件循環中啟動另一個事件循環。例如,模態對話框(Modal Dialog)通常會啟動一個嵌套的事件循環,以確保對話框在關閉之前獨占輸入焦點。

QDialog dialog;
dialog.exec();  // 啟動嵌套事件循環

????????嵌套事件循環會暫停當前事件循環,直到嵌套事件循環結束。嵌套事件循環結束后,控制權返回到上層事件循環,繼續處理剩余的事件。


7. 事件循環的阻塞

????????如果事件處理函數中執行了耗時操作(如復雜的計算、網絡請求等),可能會阻塞事件循環,導致應用程序界面無響應。為了避免這種情況,建議將耗時操作放到后臺線程中執行,從而避免阻塞主線程的事件循環。

?

QThread* thread = new QThread;
HeavyTask* task = new HeavyTask;
task->moveToThread(thread);
connect(thread, &QThread::started, task, &HeavyTask::run);
connect(task, &HeavyTask::finished, thread, &QThread::quit);
connect(task, &HeavyTask::finished, task, &HeavyTask::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();


8. 事件過濾器

????????Qt 提供了事件過濾器(Event Filter)機制,允許開發者在事件分發到目標對象之前攔截和處理事件。事件過濾器可以通過安裝 QObject::installEventFilter() 設置。

class EventFilter : public QObject {
protected:bool eventFilter(QObject* obj, QEvent* event) override {if (event->type() == QEvent::KeyPress) {// 處理按鍵事件return true;  // 表示事件已被處理}return QObject::eventFilter(obj, event);  // 傳遞給默認處理程序}
};EventFilter* filter = new EventFilter;
someObject->installEventFilter(filter);

????????事件過濾器可以用于全局事件處理、攔截特定事件等場景。


9. 自定義事件

????????開發者可以通過繼承 QEvent 創建自定義事件,并通過 QCoreApplication::postEvent() 將自定義事件發送到事件隊列中。

class CustomEvent : public QEvent {
public:static QEvent::Type eventType;  // 靜態成員變量CustomEvent() : QEvent(eventType) {}
};QEvent::Type CustomEvent::eventType = static_cast<QEvent::Type>(QEvent::registerEventType());void postCustomEvent(QObject* receiver) {QCoreApplication::postEvent(receiver, new CustomEvent());
}

????????自定義事件可以用于實現復雜的事件驅動邏輯。

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

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

相關文章

Leaflet 自定義瓦片地圖與 PHP 大圖切圖算法 解決大圖沒辦法在瀏覽器顯示的問題

為什么使用leaflet 使用 Leaflet 來加載大圖片&#xff08;尤其是通過瓦片化的方式&#xff09;是一種高效的解決方案&#xff0c;主要原因如下&#xff1a; 1. 性能優化 減少內存占用&#xff1a;直接加載大圖片會占用大量內存&#xff0c;可能導致瀏覽器崩潰或性能下降。瓦片…

一種應用非常廣泛的開源RTOS(實時操作系統):nuttx

什么是NuttX&#xff1f; NuttX&#xff08;讀音接近“納特-艾克斯”&#xff09;是一種應用非常廣泛的開源RTOS&#xff08;實時操作系統&#xff09;&#xff0c;由Gregory Nutt博士主要推動開發。RTOS&#xff0c;即 Real-Time Operating System&#xff0c;直譯為“實時操…

Python中plotext 庫詳細使用(命令行界面中直接繪制各種圖形)

更多內容請見: python3案例和總結-專欄介紹和目錄 文章目錄 plotext概述1.1 plotext介紹1.2 安裝二、基本用法2.1 簡單繪圖2.2 散點圖2.3 折線圖2.4 條形圖2.5 直方圖2.6 標題和坐標軸標簽2.7 網格和坐標軸2.8 顏色和樣式2.9 多圖疊加三、高級功能3.1 多圖繪制3.2 對數坐標3.3…

使用 ESP32 驅動 ±12V 壓電無源蜂鳴器(NPN 三極管 + PWM 控制驅動電路)

&#x1f50a; 使用 ESP32 驅動 12V 壓電無源蜂鳴器&#xff08;NPN 三極管 PWM 控制驅動電路&#xff09; 本教程將介紹如何使用 ESP32 控制一個額定工作電壓為 12V 的壓電無源蜂鳴器&#xff0c;通過 NPN 三極管 PWM 信號實現音量更大的驅動方案。 &#x1f9e0; 教程目標…

python調用金蝶api接口

金蝶接口 登錄接口 https://xxx.xxx.com/k3cloud/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc 查詢單據接口 https://xxx.xxx.com/K3Cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc 基礎資料保存接口、…

12 web 自動化之基于關鍵字+數據驅動-反射自動化框架搭建

文章目錄 一、如何實現一條用例&#xff0c;實現覆蓋所有用例的測試1、結合數據驅動&#xff1a;編輯一條用例&#xff0c;外部導入數據實現循環測試2、用例體&#xff1a;實現不同用例的操作步驟對應的斷言 二、實戰1、項目路徑總覽2、common 文件夾下的代碼文件3、keywords 文…

Ubuntu shell指定conda的python環境啟動腳本

Ubuntu shell指定conda的python環境啟動腳本。 通過指令&#xff0c;獲取目前系統的conda虛擬python環境 conda info -e 如下圖所示&#xff0c;為我自己電腦的python環境 # conda environments: # base * /home/ubuntu/miniconda3 kitti …

博客系統技術需求文檔(基于 Flask)

以下內容是AI基于要求生成的技術文檔&#xff0c;僅供參考~ &#x1f9f1; 一、系統架構設計概覽 層級 內容 前端層 HTML Jinja2 模板引擎&#xff0c;集成 Markdown 編輯器、代碼高亮 后端層 Flask 框架&#xff0c;RESTful 風格&#xff0c;Jinja2 渲染 數據庫 SQLi…

【Linux 學習計劃】-- 權限

目錄 權限是什么 權限的本質 權限&#xff08;用戶&#xff09;的修改 權限的匹配機制 目錄的權限 初始權限&#xff08;文件和目錄&#xff09; 粘滯位 結語 權限是什么 在現實世界中就有權限的概念&#xff0c;也就是&#xff0c;一部分人能做但是其他沒有相關身份的…

okcc呼叫中心系統搭建的方案方式

傳統企業呼叫中心多采用 PC和手機軟件&#xff0c;很難與客戶保持良好的溝通。因此&#xff0c;需要建設一套呼叫中心系統來實現與客戶實時有效溝通。那么&#xff0c;呼叫中心搭建的方案方式有哪些呢?下面詳細介紹一下。 呼叫中心系統的搭建方式需根據企業規模、預算和業務需…

前端最新面試題及答案 (2025)

前端最新面試題及答案 (2025) JavaScript 核心 1. ES6+ 新特性 問題: 請解釋 ES6 中 let/const 與 var 的區別,以及箭頭函數的特點。 答案: let/const vs var: 作用域: let/const 是塊級作用域,var 是函數作用域 變量提升: var會提升變量,let/const不會(有暫時性死區) 重…

傳統輪椅逆襲!RDK + 激光雷達如何重塑出行體驗?

為滿足特殊群體智能化出行需求&#xff0c;攻克傳統輪椅技術短板&#xff0c;本項目研發了一款智能輪椅。該輪椅借助攝像頭與激光雷達&#xff0c;精準感知環境、檢測障礙物&#xff1b;融合激光 SLAM 技術和互聯網地圖&#xff0c;實現室內外無縫導航與自主避障&#xff1b;提…

go-中間件的使用

中間件介紹 Gin框架允許開發者在處理請求的過程中加入用戶自己的鉤子(Hook)函數這個鉤子函數就是中間件&#xff0c;中間件適合處理一些公共的業務邏輯比如登錄認證&#xff0c;權限校驗&#xff0c;數據分頁&#xff0c;記錄日志&#xff0c;耗時統計 1.定義全局中間件 pac…

【Linux】動靜態庫鏈接原理

&#x1f4dd;前言&#xff1a; 這篇文章我們來講講Linux——動靜態庫鏈接原理 &#x1f3ac;個人簡介&#xff1a;努力學習ing &#x1f4cb;個人專欄&#xff1a;Linux &#x1f380;CSDN主頁 愚潤求學 &#x1f304;其他專欄&#xff1a;C學習筆記&#xff0c;C語言入門基礎…

第八節第三部分:認識枚舉、枚舉的作用和應用場景

認識枚舉 枚舉的概述 枚舉的特點 枚舉的應用場景 代碼&#xff1a; 代碼一&#xff1a;認識枚舉 A&#xff08;枚舉&#xff09; package com.d6_enum;public enum A {//注意&#xff1a;枚舉類的第一行必須羅列的是枚舉對象的名字X,Y,Z;private String name;public String…

Android framework 中間件開發(二)

上篇文章中我們講述了怎么去開發中間件 Android framework 中間件開發(一) 這篇我們講一下怎么打包中間件給外部應用使用 目錄 1.新建項目 2.編寫jar包代碼 3.打包jar包 4.使用jar包 我們可以直接將系統編譯出來的framework的jar包拿出來直接用,但是為了安全起見,防止用戶調用…

FC7300 IO 無法正常輸出高低電平問題排查

現象&#xff1a;Port、Dio配置正常的情況下&#xff0c;IO寫或者翻轉函數正常執行后&#xff0c;IO電平未按照預期切換電平。 排查&#xff1a; 第一步&#xff1a;檢查PORTx_PCRy寄存器值&#xff1a; DWP&#xff1a; 域寫保護&#xff1a;此字段指示允許哪個內核或 DMA 寫…

7 個正則化算法完整總結

哈嘍&#xff01;我是我不是小upper&#xff5e;之前和大家聊過各類算法的優缺點&#xff0c;還有回歸算法的總結&#xff0c;今天咱們來深入聊聊正則化算法&#xff01;這可是解決機器學習里 “過擬合” 難題的關鍵技術 —— 想象一下&#xff0c;模型就像個死記硬背的學生&am…

如何有效的開展接口自動化測試?

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 一、簡介 接口自動化測試是指使用自動化測試工具和腳本對軟件系統中的接口進行測試的過程。其目的是在軟件開發過程中&#xff0c;通過對接口的自動化測試來提高測…

我設計的一個安全的 web 系統用戶密碼管理流程

作為一名有多年經驗的前端&#xff0c;在剛開始學習web后端的時候&#xff0c;就對如何設計一個安全的 web 系統用戶密碼管理流程有很多疑問。之前自己也實踐過幾種方法&#xff0c;但一直覺得不是十分安全。 我們知道&#xff0c;用戶在注冊或登錄界面填寫的密碼是明文的&…