🌟 嗨,我是熱愛嵌入式的濤濤同學!
每日一言
????????別害怕改變,走出舒適圈才能遇見更好的自己。
實現完這個之后我們來接觸一下事件過濾器來實現這個功能吧
好的那么我們的這個事件過濾器的這個函數在QObject類里面
這邊也有相對應的代碼案例進行參考
動手直接上代碼
bool?Widget::eventFilter(QObject?*watched,?QEvent?*event)
{
????if(event->type()==QEvent::Wheel){
????????if(QGuiApplication::keyboardModifiers()==Qt::ControlModifier){
???????????????QWheelEvent?*?wheelEvent=(QWheelEvent?*)event;
???????????????if(wheelEvent->angleDelta().y()>0){
???????????????????zoomIn();
???????????????}else{
???????????????????reduce();
???????????????}
???????????????return?true;
????????}
????????return?false;
????}
}
事件過濾器也就是提前處理了,事件會經過 ?事件產生、事件派發、事件過濾、事件分發、事件處理,
那么我們事件呢就是可以直接在事件過濾器這邊實現,那么我們會發現要是我這邊寫兩個事件,一個是滾輪事件、一個是鍵盤按下事件,那么會發現無法將他們聯系在一起啊,也就是事件過濾器在同一時間只能過濾一個事件,所以我們這邊需要將滾輪事件和我們的和我們的ctrl進行綁定,那么我們該怎么辦呢,那么我們的ctrl也就是按下按鍵的這個操作不能寫成事件,
那么我們該怎么寫呢??
那么我們這邊提供一個新的用法就是QGuiAppLication::keyboradModifiers()這個函數就是檢測按鍵的狀態的,
這邊我需要講解一下
函數作用詳解
QGuiApplication::keyboardModifiers()?是一個獲取當前鍵盤修飾鍵狀態的全局函數,核心作用是:
返回當前被按下的修飾鍵(如 Ctrl、Shift、Alt 等),常用于判斷用戶是否按下了組合鍵(如 Ctrl + 滾輪、Shift + 點擊等)。
關鍵細節解析
返回值類型:Qt::KeyboardModifiers
這是一個枚舉類型,可能的返回值包括:
- Qt::NoModifier:無修飾鍵被按下。
- Qt::ControlModifier:Ctrl 鍵被按下。
- Qt::ShiftModifier:Shift 鍵被按下。
- Qt::AltModifier:Alt 鍵被按下。
- 組合值(如?Qt::ControlModifier | Qt::ShiftModifier?表示 Ctrl+Shift 同時按下)。
“當前狀態” 的含義:
函數返回的是事件隊列中最近一次更新的修飾鍵狀態(基于最近的?KeyPress?或?KeyRelease?事件),而非 “實時硬件狀態”。
- 例如:當你按下 Ctrl 鍵,Qt 會發送?KeyPress?事件,keyboardModifiers()?會更新為?Qt::ControlModifier。
- 當你釋放 Ctrl 鍵,Qt 發送?KeyRelease?事件,狀態會重置為?Qt::NoModifier。
適用場景:
用于判斷組合鍵操作,例如:
- Ctrl + 滾輪縮放(你的代碼中已使用)。
- Ctrl+C 復制、Ctrl+V 粘貼等快捷鍵。
- Shift + 點擊多選等交互邏輯。
??QWheelEvent?*?wheelEvent=(QWheelEvent?*)event;這句話是因為我們需要轉換一下,因為原本的我們的event是QEvent類型的那樣的話怎么去獲得我們的滾輪的詳細信息呢,那么我們就需要進行轉換,我們這樣的屬于是c語言的轉換方式,也可以用哈,但是還有幾種c++的專門的轉換方法
轉換完之后我們就可以依據這個滾輪中的angleDelta這個函數進行判斷,如果大于0就放大,小于0就縮小
會發現,那我們是不是還需要加上return true 啊
bool?Widget::eventFilter(QObject?*watched,?QEvent?*event)
{
????if(event->type()==QEvent::Wheel){
????????if(QGuiApplication::keyboardModifiers()==Qt::ControlModifier){
???????????????QWheelEvent?*?wheelEvent=(QWheelEvent?*)event;
???????????????if(wheelEvent->angleDelta().y()>0){
???????????????????zoomIn();
???????????????}else{
???????????????????reduce();
???????????????}
???????????????return?true;
????????}
????????return?false;
????}
}
總結
轉換的目的是:將通用的事件基類指針,轉換為具體的事件子類指針,從而訪問該事件特有的屬性和方法。
會發現我們沒有用到這個watched,
總結
你的代碼中?watched?未被使用,說明這個過濾器是 **“通用型”** 的(對所有被監聽控件生效)。如果未來需要限制縮放功能只對特定控件生效(比如只讓文本框縮放,按鈕不縮放),就需要通過?watched?來判斷對象類型或名稱,實現更精確的控制。
這正是?watched?參數的意義:讓事件過濾器可以根據事件來源靈活處理不同控件的事件。
Tips:eventFilter()?函數本身是?QObject?類的虛函數(默認實現為空),需要我們在自定義類中重寫它,并通過?installEventFilter()?將其安裝到目標對象上,才能生效。
1. 事件過濾器的工作流程
默認狀態:
所有?QObject?子類都有?eventFilter()?函數,但默認實現為空(直接返回?false),不會攔截任何事件。
重寫并安裝:
我們需要在自定義類(如?Widget)中重寫?eventFilter(),并通過?target->installEventFilter(this)?將其安裝到目標對象(target)上。
事件分發:
當?target?接收到事件時,Qt 會先調用其安裝的事件過濾器,再將事件傳遞給?target?自身的事件處理函數。
好的那么我們的記事本項目就完結了,認真學下來會發現學會了很多,從剛開始的懵懵懂懂,到后面會發現我們對Qt手冊更會使用了,也就是我們學習QT也就是轉換為學習怎么使用QT手冊了,因為QT的類有上萬個,我們不可能學的完,但是常用的類有幾十個,所以我們就是要記住我們現在所學的任何一個類和其中的函數,知道怎么尋找,這個就是我們學QT的得出的經驗。