Qt:事件

目錄

處理事件

鼠標事件

鍵盤事件

定時器事件

窗口事件


雖然 Qt 是跨平臺的 C++ 開發框架,Qt 的很多能力其實是操作系統提供的
只不過 Qt 封裝了系統的 API

事件

前面學習過信號槽:
用戶進行的各種操作,就可能會產生出信號,可以給某個信號指定槽函數,當信號觸發時,就能夠自動的執行到對應的槽函數

事件和信號槽非常類似:
用戶進行的各種操作,也會產生事件,程序員同樣可以給事件關聯上處理函數(處理的邏輯),當事件觸發的時候,就能夠執行到對應的代碼

事件本身是操作系統提供的機制,Qt 也同樣把操作系統事件機制進行了封裝,拿到了 Qt 中
但是由于事件對應的代碼編寫起來不是很方便,所以 Qt 對于事件機制又進行了進一步的封裝,就得到了信號槽

信號槽就是對于事件的進一步封裝,事件是信號槽的底層機制

實際 Qt 開發程序過程中,絕大部分和用戶之間進行的交互都是通過"信號槽"來完成的
有些特殊情況下,信號槽不一定能搞定(某個用戶的動作行為,Qt 沒有提供對應的信號)
此時就需要通過重寫事件處理函數的形式,來手動處理事件的啊應邏輯

開發事件機制給咱們程序員,咱們就可以根據實際的需要進行更深度的定制化 diy 操作了

用戶進行了很多操作,就會產生很多的事件(當然也會產生很多的信號)

下面就是開發中比較典型的事件:

不同場景下,要關注的點是不一樣,這些事件的子類中就會包含一些對應的不同的屬性


處理事件

讓一段代碼和某個事件關聯起來,當事件觸發的時候,就能指定到這段代碼
之前信號槽這里通過 connect 來完成上述關聯的

對于事件來說,還不太一樣:
讓當前的類,重寫某個事件處理函數,這里用到的是"多態”機制
創建子類, 繼承自 Qt 已有的類,在子類中重寫父類的事件處理函數
后續事件觸發過程中,就會通過多態這樣的機制,執行到咱們自己寫的子類的函數中

鼠標事件

下面都是創建 QWidget 的,當然也可以創建 QMainWindow,因為用不到工具欄,所以選擇的 QWidget

鼠標進入和鼠標離開事件

下面使用上述方式,處理一下鼠標進入(enterEvent)和鼠標離開(leaveEvent)事件:
enterEvent 和?leaveEvent 函數都是虛函數,所以可以被子類重寫:

圖形化界面的方式創建一個 Label,鼠標進入 Label 時提示 enterEvent,離開時提示?leaveEvent:
為了能清楚看到 Label 的邊框,將邊框選為 Box

?效果為:

這里需要創建 QLabel 的子類,重寫 enterEvent 和 leaveEvent:

類名就叫 Label,父類叫 QLabel:

按照以往的習慣,創建的 Label 類需要有一個父控件,所以在 label.h 中添加:

label.cpp 中添加:


接著在 label.h 中聲明兩個需要重寫的函數:

注意:
要想重寫父類的函數,就需要確保你這邊寫的函數名字和函數的參數列表都完全一致 (形參名無所謂),謹防單詞拼寫錯誤

label.cpp 實現:

(void)event 是為了消除警告,因為暫時還沒用到 event 這個形參

此時運行程序,鼠標進入和移出 label 時并沒有執行上述邏輯,因為:
當前在界面上創建的這個 label 其實是 QLabel,不是咱們自己寫的 Label
必須要確保界面上的這個 label 是一個咱們自己定義的 Label 類的實例,才會執行到

右鍵圖形化界面的 label,點擊提升為:

輸入提升的類名 Label,點擊添加,再點擊提升:
一定要確保你的類名以及頭文件的名字,和上述自定義的類名頭文件都匹配

此時右邊對象樹上面就是 Label 了,沒提升前顯示是 QLabel:

通過"提升為"這樣的方式,就可以把 Qt Designer 中拖上去的控件的類型轉換成自定義的控件類型

此時再運行程序,鼠標移入移出 Label 時,就會打印下面的內容了:

此時就說明當前的 enterEvent 和 leaveEvent 這兩個事件就被咱們給捕獲到了


通過事件獲取到鼠標點擊的位置

與上面的操作一樣,創建一個 Label,再創建一個 Label 類,父類定為 QLabel,并對生成的 Label 的構造函數做一個調整,添加一個 QWidget* 的參數,以便于能夠指定父窗口
接著再右鍵 Label 點擊提升為,輸入類名后點擊提升,此時就完成了提升操作:

下面就是 mousePressEvent 函數,當鼠標按下時就會觸發這個函數調用:
左鍵、右鍵、滾輪、側鍵都能觸發

在 label.cpp 中實現 mousePressEvent 函數:

此時鼠標在 Label 范圍內點擊就會打印 鼠標點擊的位置坐標:
上述是以 Label 左上角位置為原點的

下面則是以屏幕左上角為原點獲取坐標:

也可以加上下面的代碼,來判斷按下的是左鍵還是右鍵:


通過事件獲取到鼠標點擊釋放按鍵

與上面的鼠標點擊事件一樣,下面是重寫的 mouseReleaseEvent 函數:

此時就能做到獲取鼠標點擊釋放按鍵:

clicked 這樣的信號,就相當于是一次鼠標按下事件和一次鼠標釋放事件


通過事件獲取到鼠標雙擊按鍵

重寫的 mouseDoubleEvent 函數如下:

鼠標第二次按下的時候,才能夠識別到是"雙擊:

注意:
有的程序,可能是單擊有一些邏輯,雙擊有另一些邏輯,如果我們沒注意,可能雙擊操作就能觸發單擊的邏輯,可能就有 bug


通過事件獲取到鼠標移動

剛才重寫鼠標事件的操作,都是在自定義的 Labe| 中完成的,此時鼠標只有在 Label 范圍內進行動作的時候,才能捕獲到
也可以把這些操作直接放到 Widget (QWidqet 子類) 來完成,這樣的話,鼠標在整個窗口中進行的各種動作都能獲取到了

所以直接在 widget.h widget.cpp 中重寫 mouseMoveEvent 函數:

此時運行程序并沒有效果

鼠標移動不同于鼠標按下
隨便移動一下鼠標,就會產生出大量的鼠標移動事件,當你進行捕獲事件的時候,尤其是在這里再進行一些復雜邏輯的時候,程序負擔就很重,很容易產生卡頓之類的情況
Qt 為了保證程序的流暢性,默認情況下不會對鼠標移動進行追蹤,鼠標移動的時候不會調用mouseMoveEvent,除非顯式告訴 Qt 就要追蹤鼠標位置

所以需要在 Widget 的構造函數中設置:

此時稍微一動鼠標,就會一直打印,如果移動的比較快,就會明顯出現打印卡頓的情況:


通過事件獲取到鼠標滾輪的滾動動作

在 QWheelEvent 中 通過 delta() 獲取到這次事件鼠標滾輪滾動了多遠

同樣在 widget.h widget.cpp 中重寫 wheelEvent 函數:

滾輪往下滾動就打印?-120,往上滾動就打印?120:

我們也可以在 Widget 類中新增 int total,初始化為0,就能在 wheelEvent 函數中實現統計滾輪滾動的距離了:

效果為:

就可以根據滾輪滾動的操作實現特定的功能,比如可以通過滾輪去縮放字體大小,可以把滾輪滾動的距離映射到具體的數值上,就可以實現類似的效果了


鍵盤事件

處理鍵盤按鍵事件

我們前面學習過的 QShortCut,這是信號槽機制封裝過的,獲取鍵盤按鍵的方式

站在更底層的角度,也可以通過事件獲取到當前用戶鍵盤按下的情況

依舊是在?widget.h widget.cpp 中重寫 keyPressEvent 函數:

按下 ABCDEF 的效果為,可以發現每一個按鈕都對應一個數字:

如果想得知是否按下了具體的某一個鍵,以 A 為例,代碼改為:

也有些場景是組合鍵 Ctrl + A :


定時器事件

前面學習了QTimer 實現定時器功能
在 QTimer 背后是 QTimerEvent 定時器事件進行支撐的

QObject 提供了一個 timerEvent 這個函數,可以通過定時器,周期性的觸發一些操作
里面需要搭配?startTimer 啟動定時器,killTimer 關閉定時器 使用

下面通過圖形化的方式,拖動一個 LCD Number,初始值改為 10 :

此處 startTimer 的返回值 timerld 類似于 Linux 中的文件描述符,起到的是身份標識的效果

因為后面程序可能還會用到?timerld,所以在 widget.h 中的構造函數定義為類內成員:

在?widget.h widget.cpp 中重寫 timerEvent 函數:

運行程序,每隔一秒-1,直到0就停止:

使用 timerEvent 比 QTimer 還是要更復雜一點,手動管理 timerld,還需要區分這次函數調用是哪個 timer 引起的
后續實際開發中,使用 QTimer 即可


窗口事件

  • moveEvent 窗口移動時觸發的事件
  • resizeEvent 窗口大小改變時觸發的事件

?moveEvent

QMoveEvent 中有下面兩個常用的方法:

resizeEvent

QResizeEvent 中有下面兩個常用的方法:


在?widget.h widget.cpp 中重寫 moveEvent 和 resizeEvent函數:

如果移動 widget 窗口或調整 widget 窗口大小,下面就會打印:


Qt:事件相關知識到此結束

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

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

相關文章

責任鏈模式:優雅處理復雜流程的設計藝術

引言 在軟件設計中,我們經常會遇到需要按特定順序處理請求的場景。例如,一個訂單處理系統可能需要經過驗證、付款、物流安排和客戶通知等多個步驟。如果我們將這些步驟硬編碼在一個方法中,代碼將變得臃腫且難以維護。這時,責任鏈…

【STM32】玩轉IIC之驅動MPU6050及姿態解算

目錄 前言 一.MPU6050模塊介紹 1.1MPU6050簡介 1.2 MPU6050的引腳定義 1.3MPU6050寄存器解析 二.MPU6050驅動開發 2.1 配置寄存器 2.2對MPU6050寄存器進行讀寫 2.2.1 寫入寄存器 2.2.2讀取寄存器 2.3 初始化MPU6050 2.3.1 設置工作模式 2.3.2 配置采樣率 2.3.3 啟…

【ThreeJS Basics 09】Debug

文章目錄 簡介從 dat.GUI 到 lil-gui例子安裝 lil-gui 并實例化不同類型的調整改變位置針對非屬性的調整復選框顏色 功能/按鈕調整幾何形狀文件夾調整 GUI寬度標題關閉文件夾隱藏按鍵切換 結論 簡介 每一個創意項目的一個基本方面是能夠輕松調整。開發人員和參與項目的其他參與…

【Pandas】pandas Series explode

Pandas2.2 Series Computations descriptive stats 方法描述Series.argsort([axis, kind, order, stable])用于返回 Series 中元素排序后的索引位置的方法Series.argmin([axis, skipna])用于返回 Series 中最小值索引位置的方法Series.argmax([axis, skipna])用于返回 Series…

電腦網絡出現問題!簡單的幾種方法解除電腦飛行模式

在某些情況下,您可能需要關閉電腦上的飛行模式以便重新連接到 Wi-Fi、藍牙或其他無線網絡。本教程中簡鹿辦公將指導您如何在 Windows 和 macO S操作系統上解除飛行模式。 一、Windows 系統下解除飛行模式 通過快捷操作中心 步驟一:點擊屏幕右下角的通知…

nature genetics | SCENT:單細胞多模態數據揭示組織特異性增強子基因圖譜,并可識別致病等位基因

–https://doi.org/10.1038/s41588-024-01682-1 Tissue-specific enhancer–gene maps from multimodal single-cell data identify causal disease alleles 研究團隊和單位 Alkes L. Price–Broad Institute of MIT and Harvard Soumya Raychaudhuri–Harvard Medical S…

MyBatis-Plus 與 Spring Boot 的最佳實踐

在現代 Java 開發中,MyBatis-Plus 和 Spring Boot 的結合已經成為了一種非常流行的技術棧。MyBatis-Plus 是 MyBatis 的增強工具,提供了許多便捷的功能,而 Spring Boot 則簡化了 Spring 應用的開發流程。本文將探討如何將 MyBatis-Plus 與 Spring Boot 進行整合,并分享一些…

uploadlabs通關思路

目錄 靶場準備 復現 pass-01 代碼審計 執行邏輯 文件上傳 方法一:直接修改或刪除js腳本 方法二:修改文件后綴 pass-02 代碼審計 文件上傳 1. 思路 2. 實操 pass-03 代碼審計 過程: 文件上傳 pass-04 代碼審計 文件上傳 p…

AI編程工具節選

1、文心快碼 百度基于文心大模型推出的一款智能編碼助手, 官網地址:文心快碼(Baidu Comate)更懂你的智能代碼助手 2、通義靈碼 阿里云出品的一款基于通義大模型的智能編碼輔助工具, 官網地址:通義靈碼_你的智能編碼助手-阿里云 …

目錄掃描工具深度對比:Dirb、Dirsearch、DirBuster、Feroxbuster 與 Gobuster

? 前言 在網絡安全測試與滲透測試中,目錄掃描(又稱目錄枚舉)是一項至關重要的技術。它用于發現 Web 服務器上未公開的隱藏目錄和文件,這些資源可能包含敏感數據、配置文件甚至潛在漏洞,因而成為攻擊者與安全研究人員…

“雙碳”背景下,企業應該如何提升能源效率?

在當今競爭激烈的市場環境中,企業不僅需要優化成本,還需積極響應國家的能源政策,減少對環境的影響。提升工業能源效率正是實現這一雙重目標的關鍵。中國近年來大力推進“雙碳”目標(碳達峰、碳中和),并出臺…

無人機擴頻技術對比!

一、技術原理與核心差異 FHSS(跳頻擴頻) 核心原理:通過偽隨機序列控制載波頻率在多個頻點上快速跳變,收發雙方需同步跳頻序列。信號在某一時刻僅占用窄帶頻譜,但整體覆蓋寬頻帶。 技術特點: 抗干擾…

當AI開始“思考“:拆解大模型訓練與推理的秘密(以DeepSeek為例)

如果你用過deepseek,可能體驗過它在幾秒內編故事、寫代碼的震撼。但你是否想過,這種"智能輸出"背后存在兩種完全不同的底層機制?就像人類需要先學習知識(訓練)才能考試答題(推理)&…

永洪科技深度分析實戰,零售企業的銷量預測

隨著人工智能技術的不斷發展,智能預測已經成為各個領域的重要應用之一。現在,智能預測技術已經廣泛應用于金融、零售、醫療、能源等領域,為企業和個人提供決策支持。 智能預測技術通過分析大量的數據,利用機器學習和深度學習算法…

Vue項目通過內嵌iframe訪問另一個vue頁面,獲取token適配后端鑒權(以內嵌若依項目舉例)

1. 改造子Vue項目進行適配(ruoyi舉例) (1) 在路由文件添加需要被外鏈的vue頁面配置 // 若依項目的話是 router/index.js文件 {path: /contrast,component: () > import(/views/contrast/index),hidden: true },(2) 開放白名單 // 若依項目的話是 permission.js 文件 cons…

【DeepSeek】5分鐘快速實現本地化部署教程

一、快捷部署 (1)下載ds大模型安裝助手,下載后直接點擊快速安裝即可。 https://file-cdn-deepseek.fanqiesoft.cn/deepseek/deepseek_28348_st.exe (2)打開軟件,點擊立即激活 (3)選…

Linux第一課

如何在Windows系統上安裝紅帽Linux虛擬機 一:下載VNware 下載鏈接:Desktop Hypervisor Solutions | VMware 二:下載操作系統鏡像文件 在阿里云開源鏡像站下載(本文章下載 red hat 9.3) 阿里云開源鏡像站鏈接:阿里巴巴開源鏡像站-OPSX鏡像站-阿里云開發者社區 三:創建虛擬機文…

語音分離:使用短時能量提取主聲源

語音分離模型:mossfomer2 計算短時能量 def compute_short_time_energy(audio: np.ndarray, frame_size: int, hop_size: int) -> np.ndarray:"""計算音頻信號的短時能量 將音頻分為若干幀,每一幀長度為 frame_size, 幀與幀之間以 h…

【VUE】第二期——生命周期及工程化

目錄 1 生命周期 1.1 介紹 1.2 鉤子 2 可視化圖表庫 3 腳手架Vue CLI 3.1 使用步驟 3.2 項目目錄介紹 3.3 main.js入口文件代碼介紹 4 組件化開發 4.1 組件 4.2 普通組件注冊 4.2.1 局部注冊 4.2.2 全局注冊 1 生命周期 1.1 介紹 Vue生命周期:就是…

SyntaxError: Unexpected keyword ‘else‘

🤍 前端開發工程師、技術日更博主、已過CET6 🍨 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 🕠 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》、《前端求職突破計劃》 🍚 藍橋云課簽約作者、…