雖然 Qt 是跨平臺的 C++ 開發框架,Qt 有很多能力其實是操作系統提供的,只不過 Qt 封裝了系統的 API
程序時運行在操作系統上的,需要系統給我們提供支撐!
- 事件
- 文件操作
- 多線程編程
- 網絡編程
- 多媒體(音頻,視頻)
Qt 事件
事件介紹
信號槽:用戶進行的各種操作可能會產生出信號,我們可以給某個信號指定槽函數,當信號觸發時,就能夠自動的執行到對應的槽函數!
事件也是非常類似的,用戶進行的各種操作,也會產生事件,程序員同樣可以給事件關聯上處理函數(處理的邏輯),當事件觸發的時候,就能夠執行到對應的代碼!
事件本身是操作系統提供的機制,Qt? 也同樣把操作系統事件進行了封裝,拿到了 Qt 中!但是由于事件對應的代碼編寫不是很方便,所以 Qt 對于事件這樣的機制又進行了封裝,就得到了信號槽!
所以事件就是信號槽的底層機制!實際 Qt 開發程序過程中,絕大部分和用戶之間進行的交互是通過“信號槽”來完成的!但是對于有些特殊情況,信號槽不一定能搞定(某個用戶的動作行為,Qt 沒有提供對應的信號...這時候我們就需要通過重寫事件的處理函數的形式,來手動處理事件的響應邏輯)
事件是應用程序內部或者外部產生的事情或者動作的統稱。在 Qt 中使用一個對象來表示一個事件。所有的 Qt 事件均繼承于抽象類 QEvent。事件是由系統或者 Qt 平臺本身在不同的時刻發出的。當用戶按下鼠標、敲下鍵盤,或者是窗口需要重新繪制的時候,都會發出一個相應的事件。一些事件是在用戶操作時發出,如鍵盤事件、鼠標事件等,另一些事件則是由系統本身自動發出,如定時器事件。常見的 Qt 事件如下:
常見事件描述:
事件名稱 | 描述 |
---|---|
鼠標事件 | 鼠標左鍵、鼠標右鍵、鼠標滾輪,鼠標的移動,鼠標按鍵的按下和松開 |
鍵盤事件 | 按鍵類型、按鍵按下、按鍵松開 |
定時器事件 | 定時時間到達 |
進入離開事件 | 鼠標的進入和離開 |
滾輪事件 | 鼠標滾輪滾動 |
繪屏事件 | 重繪屏幕的某些部分 |
顯示隱藏事件 | 窗口的顯示和隱藏 |
移動事件 | 窗口位置的變化 |
窗口事件 | 是否為當前窗口 |
大小改變事件 | 窗口大小改變 |
焦點事件 | 鍵盤焦點移動 |
拖拽事件 | 用鼠標進行拖拽 |
事件的處理
讓一段代碼和某一個事件關聯起來,當事件觸發的時候,就能指定到這段代碼
之前信號槽是通過 connect 來完成上述關聯的!對于事件來說,還不太一樣:
事件處理一般常用的方法為:重寫相關的 Event 函數。(用到了面向對象的多態的機制:創建子類,然后繼承自 Qt 中已有的類,在子類中重寫父類的事件處理函數,后續事件出發過程中,就會通過多態這樣的機制,執行到咱們自己寫的子類的函數中!)
在 Qt 中,幾乎所有的 Event 函數都是虛函數,所以可以重新實現。如:在實現鼠標的進入和離開控件時,直接重新實現 enterEvent() 和 leaveEvent() 即可。enterEvent() 和 leaveEvent() 函數原型如下:
[virtual protected] void QWidget::enterEvent(QEvent *event)
This event handler can be reimplemented in a subclass to receive widget enter events which are passed in the
event
parameter. An event is sent to the widget when the mouse cursor enters the widget.See also leaveEvent(), mouseMoveEvent(), and event().
[virtual protected] void QWidget::leaveEvent(QEvent *event)
This event handler can be reimplemented in a subclass to receive widget leave events which are passed in the
event
parameter. A leave event is sent to the widget when the mouse cursor leaves the widget.See also enterEvent(), mouseMoveEvent(), and event().
示例1:
1. 新建 Qt 項目,基類選擇 QWidget,同時勾選 UI 界面文件,如下圖所示:
2. 設計 ui 文件,如下所示:
3. 在項目中新添加一個類:MyLabel;
創建 QLable 子類,重寫 enterEvent 和 leaveEvent!
先選中項目名稱 QEvent,點擊鼠標右鍵,選擇 add new ...,彈出如下對話框:
4. 選擇:Choose ...,彈出如下界面:
5. 此時項目會新增如下兩個文件:
6. 在幫助文檔中查找對應的內容:
7. 點擊“顯示”之后,出現如下內容:
[virtual protected] void QWidget::enterEvent(QEvent *event)
This event handler can be reimplemented in a subclass to receive widget enter events which are passed in the
event
parameter. An event is sent to the widget when the mouse cursor enters the widget.See also leaveEvent(), mouseMoveEvent(), and event().
8.?復制 enterEvent() ,粘貼在項??件 "mylabel.h" 中:
9.?重寫 enterEvent() ?法:
10.?在 UI ?件中選中 Label,右鍵 ------> 提升為...
我們直接執行是不行的!
因為當前界面上創建的這個 label 其實是QLabel,不是我們自己寫的 MyLabel!
必須要確保界面上的這個 label 是一個咱們自己定義的 Mylabel 的示例,才會執行到!
11. 當點擊 "提升為... " 之后,彈出如下對話框:
12. 修改基類:
13.?執?效果如下:當?標進?設計好的標簽之后,就會在應?程序輸出欄中打印:?標進?:
示例2:當鼠標點擊時,獲取對應的坐標值
1. 在上述示例的基礎上,在 mylabel.h
中聲明 mousePressEvent()
方法:
#ifndef MYLABEL_H
#define MYLABEL_H#include <QLabel>class MyLabel : public QLabel
{Q_OBJECT
public:explicit MyLabel(QWidget *parent = nullptr);// 鼠標進入事件void enterEvent(QEvent *ev);// 鼠標移動事件void mousePressEvent(QMouseEvent *ev);signals:};#endif // MYLABEL_H
2. 在 mylabel.cpp
中重寫 mousePressEvent()
方法:
#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
}void MyLabel::enterEvent(QEvent *ev)
{qDebug() << "鼠標進入";
}void MyLabel::mousePressEvent(QMouseEvent *ev)
{// Qt中的格式化字符串QString str1 = QString("鼠標按下了 x = %1, y = %2").arg(ev->x()).arg(ev->y());qDebug() << str1;
}
實現效果如下:
鼠標進入
"鼠標按下了 x = 54, y = 61"
"鼠標按下了 x = 234, y = 15"
"鼠標按下了 x = 393, y = 51"
"鼠標按下了 x = 180, y = 140"
"鼠標按下了 x = 488, y = 146"
示例:鼠標左鍵點擊時,打印對應的坐標值,鼠標右鍵點擊時,打印基于屏幕的坐標
void MyLabel::mousePressEvent(QMouseEvent *ev)
{// 鼠標左鍵if(ev->button() == Qt::LeftButton){// x,y為基于窗口的坐標QString str = QString("鼠標左鍵:x = %1, y = %2").arg(ev->x()).arg(ev->y());qDebug() << str.toUtf8().data();}// 鼠標右鍵if(ev->button() == Qt::RightButton){// globalX,globalY為基于屏幕的坐標QString str = QString("鼠標右鍵:x = %1, y = %2").arg(ev->globalX()).arg(ev->globalY());qDebug() << str.toUtf8().data();}
}
按鍵事件
Qt 中的按鍵事件是通過 QKeyEvent
類來實現的。當鍵盤上的按鍵被按下或者被釋放時,鍵盤事件便會觸發。在幫助文檔中查找 QKeyEvent
類如下:
查找按鍵事件中所有的按鍵類型:在幫助?檔中輸?:Qt::Key,如下圖:
單個按鍵事件處理
示例:當某個按鍵被按下時,輸出提示信息:“某個按鍵被按下了”。
1. 新建項目:在項目的頭文件 widget.h
中聲明一個虛函數 keyPressEvent()
。
2. 在 "widget.cpp" ?件中重寫 keyPressEvent() 虛函數;
組合按鍵
在 Qt 助?中搜索:Qt::KeyboardModifier,如下圖?:
在Qt中,鍵盤事件可以通過Qt::KeyboardModifier
枚舉來處理,該枚舉定義了在處理鍵盤事件時對應的修飾鍵。以下是Qt::KeyboardModifier
中定義的修飾鍵及其描述:
常量 | 描述 |
---|---|
Qt::NoModifier | 無修改鍵 |
Qt::ShiftModifier | Shift 鍵 |
Qt::ControlModifier | Ctrl 鍵 |
Qt::AltModifier | Alt 鍵 |
Qt::MetaModifier | Meta鍵(在Windows上指Windows鍵,在macOS上指Command鍵) |
Qt::KeypadModifier | 使用鍵盤上的數字鍵盤進行輸入時,Num Lock鍵處于打開狀態 |
Qt::GroupSwitchModifier | 用于在輸入法組之間切換 |
這些修飾鍵在Qt中可以與鍵盤事件一起使用,以實現一些復雜的交互操作。例如,在處理鍵盤事件時,可以通過檢查這些修飾鍵的狀態來判斷用戶是否同時按下了特定的組合鍵。
示例:
鼠標事件
在 Qt 中,鼠標事件是用 QMouseEvent 類來實現的。當在窗口中按下鼠標或者移動鼠標時,都會產生鼠標事件。
利用 QMouseEvent 類可以獲取鼠標的哪個鍵被按下了以及鼠標的當前位置等信息。在 Qt 幫助文檔中查找QMouseEvent類 如下圖所示:
鼠標單擊事件
在 Qt 中,鼠標按下是通過虛函數 mousePressEvent() 來捕獲的。mousePressEvent() 函數原型如下:
[virtual protected] void QWidget::mousePressEvent(QMouseEvent *event)
鼠標左右鍵及滾的表示如下:
Qt::LeftButton 鼠標左鍵
Qt::RightButton 鼠標右鍵
Qt::MidButton 鼠標滾輪
示例1:鼠標左鍵
1. 在 "widget.h" 頭文件中聲明鼠標按下事件;
2.?在 "widget.cpp" ?件中重新實現 mousePressEvent() 函數;
實現效果如下:
示例2:鼠標右鍵
實現效果如下:
示例3:鼠標滾輪
實現效果如下:
鼠標釋放事件
鼠標釋放事件是通過虛函數 mouseReleaseEvent() 來捕獲的。mouseReleaseEvent() 函數原型如下:
[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event)
示例:
執行效果如下:
鼠標雙擊事件
鼠標雙擊事件是通過虛函數:mouseDoubleClickEvent() 來實現的。mouseDoubleClickEvent() 函數原型如下:
[virtual protected] void QWidget::mouseDoubleClickEvent(QMouseEvent *event)
示例:鼠標左鍵雙擊
執行效果如下:
鼠標移動事件
鼠標移動事件是通過虛函數:mouseMoveEvent() 來實現的。同時為了實時捕獲鼠標位置信息,需要通過函數 setMouseTracking() 來追蹤鼠標的位置。mouseMoveEvent() 函數原型如下:
[virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event)
setMouseTracking() 函數原型如下:
void setMouseTracking(bool enable)
說明:
setMouseTracking() 函數默認是 false,需要設置為 true,才能實時捕獲鼠標位置信息。否則只有當鼠標按下時才能捕獲其位置信息。
示例:
執行效果:
滾輪事件
在 Qt 中,鼠標滾輪事件是通過 QWheelEvent 類來實現的。滾輪滑動的距離可以通過 delta() 函數獲取。delta() 函數原型如下:
int QGraphicsSceneWheelEvent::delta() const
其中返回值代表滾輪滑動的距離。正數表示滾輪相對于用戶向前滑動,負數表示滾輪相對于用戶向后滑動。
示例:
執行效果如下: