Qt事件系統之三 鍵盤事件

2022-02-20 16:08:32 字數 4085 閱讀 2361

qkeyevent 類用來描述乙個鍵盤事件。當鍵盤按鍵被按下或者被釋放時,鍵盤事件便會被傳送給擁有鍵盤輸人焦點的部件。

qkeyevent 的 key() 函式可以獲取具體的按鍵,對於 qt 中給定的所有按鍵,可以在幫助中檢視 qt: :key 關鍵字。需要特別說明的是,回車鍵在這裡是 qt::key_return;鍵盤上的一些修飾鍵,比如 ctrl 和 shift 等, 這裡需要使用 qkeyevent 的 modifiers() 函式來獲取,可以在幫助中使用 qt:: keyboardmodifier 關鍵字來檢視所有的修飾鍵。

qkeyevent 有兩個鍵盤事件成員函式,在標頭檔案.h中進行宣告:

#include protected:

void keypressevent(qkeyevent *event); //鍵盤按下事件

void keyreleaseevent(qkeyevent *event); //鍵盤鬆開事件

下面是些常用操作:

// 鍵盤按下事件

void widget::keypressevent(qkeyevent * event)

// 兩鍵組合

if(event->modifiers() == qt::controlmodifier)

}if(event->modifiers() == qt::altmodifier)

if(event->modifiers() == qt::shiftmodifier)

// 三鍵組合shift + ctrl + a的實現

if (event->modifiers() == (qt::shiftmodifier | qt::controlmodifier) && event->key() == qt::key_a)

}// 鍵盤釋放事件

void widget::keyreleaseevent(qkeyevent *event)

}

分別按下 esc、enter、ctrl + m、alt + m 等鍵,「應用程式輸出」視窗輸出如下:

esc

enter

ctrl + m

alt + m

release: up

下圖列出了所有的修飾鍵:

自動重複是指按下鍵盤上的鍵(修飾鍵除外)不放時,會不斷重複的傳送鍵按下事件,qt 預設是啟用自動重複的,若要實現類似按鍵 a+d 之類的快捷鍵,就需要關閉自動重複。可使用如下方法來關閉自動重複:

// 若自動重複則什麼也不做

if(qkeyevent::isautorepeat())

return;

qt 的鍵盤事件整體表現為,按住乙個鍵時:

1、第一次觸發 keypressevent(),isautorepeat() 返回 false

2、沒有觸發 keyreleaseevent(),停頓一會

3、再一次觸發 keypressevent(),isautorepeat() 返回true

4、觸發 keyreleaseevent()

5、若沒鬆開按鍵,isautorepeat() 返回 true,返回第 3 步;若鬆開按鍵,isautorepeat() 返回 false

可以只指定視窗中的某個控制項捕獲鍵盤事件,使其他控制項無法獲得鍵盤事件,示例如下。

mybutton.h:

#ifndef mybutton_h

#define mybutton_h

#include #include #include #include class mybutton : public qpushbutton

;#endif // mybutton_h

mybutton.cpp

#include "mybutton.h"

mybutton::mybutton(qwidget *parent) : qpushbutton(parent)

void mybutton::keypressevent(qkeyevent *event)

}

widget.h:

#ifndef widget_h

#define widget_h

#include #include #include #include "mybutton.h"

class widget : public qwidget

;#endif // widget_h

widget.cpp:

#include "widget.h"

widget::widget(qwidget *parent)

: qwidget(parent)

void widget::keypressevent(qkeyevent *event)

按下任何鍵,發現只有按鈕 aaa 才能獲得鍵盤事件,按鈕 bbb 無法獲得鍵盤事件。

首先鍵盤按鍵的單擊、雙擊實現用的 qtimer,一說到這估計大部分人都知道怎麼回事了,但這裡也有個誤區,那就是如何區分單擊和雙擊的問題。這裡使用兩次按鍵的時間間隔來區分,這裡在按下、或釋放裡實現都是可以的,這裡我最後選擇在釋放裡實現,後面再說原因。

#ifndef widget_h

#define widget_h

#include #include #include #include class widget : public qwidget

;#endif // widget_h

再看鍵盤按鍵單擊、雙擊實現:

#include "widget.h"

widget::widget(qwidget *parent)

: qwidget(parent));}

void widget::keyreleaseevent(qkeyevent *event)}}

單擊,在 500ms 內未達到雙擊次數,也就是未執行 timer_->stop(); 時間耗盡觸發 timeout 訊號,執行單擊動作。這裡提一下 stop() 函式,qtimer 執行 start(n) 後,如果不 stop(),那它會迴圈執行。

至此實現鍵盤單擊和雙擊復用,那麼我們再來看一下長按怎麼處理呢?

為了區分是否是長按,qkeyevent 提供了乙個 isautorepeat() 函式自動檢測按鍵是否長按

前面提到單擊和雙擊的區分,其實在void keypressevent(qkeyevent *event)void keyreleaseevent(qkeyevent *event)函式裡都可以,反正都是記錄時間差,press-press 或 release-release 沒分別,那最後為什麼選擇在按鍵釋放函式裡實現呢?

問題就在還得同時實現長按功能,剛剛分析得出無論你長按還是非長按,第一次的 press 動作他都是按下非長按的,如果在void keypressevent(qkeyevent *event)裡實現,那長按必然會附加一次單擊,這當然不是我們想要的;

至此分析完畢,我想我們該開始寫**了。

#include "widget.h"

widget::widget(qwidget *parent)

: qwidget(parent));}

void widget::keyreleaseevent(qkeyevent *event)

m_nclickcnt++;

if (m_nclickcnt == 2)

}m_blongpress = false; // 置false

}else}}

}

參考:qt5--鍵盤事件

qt實現鍵盤復用:單擊、雙擊、長按

QT鍵盤事件

有按下後鬆開事件 virtual void keypressevent qkeyevent event 鍵盤按下事件 virtual void keyreleaseevent qkeyevent event 鍵盤鬆開事件加個頭檔案 include在一些程式中,我們發現這樣並不好使,怎麼回事呢?這時候...

QT 之鍵盤事件(捕獲鍵盤按下 鬆開事件)

我們在做軟體時候,經常會碰到這樣的場景,比如按下f5進行重新整理功能,按下f1進行幫助之類的快捷鍵方式。那麼在qt中該怎樣做呢?查閱文件,qt已經實現了這一系列的鍵盤事件 void qwidget keypressevent qkeyevent event 鍵盤按下事件 void qwidget k...

Qt事件系統

在qt中,事件是繼承了虛擬類qevent 的物件,它代表了程式所發生的事情或者程式需要知道的乙個外部活動的結果。事件可以被任意 qobject 子類的例項接收和處理,是與widgets 當發生乙個事件,qt通過構造乙個適當的 qevent 子類的例項來建立事件物件來代表它,並通過呼叫vevent 函...