事件處理
事件是應用程序內部或者外部產生的事情或者動作的統稱。 在 Qt 中,事件是用一個對象來管理一個事件的。所有的事件對象都繼承自抽象類 QEvent
。事件包括鼠標事件、鍵盤事件等,發出自 Qt 或操作系統本身。
處理事件一般通過重寫相關的 Event 函數來實現,Qt 中所有的 Event 函數都是虛函數,都可以進行重寫。這通常需要自定義一些控件類來繼承 Qt 的控件類(如創建 Label
類繼承 QLabel
類),但 ui 界面拖拽出來的控件類型都是 Qt 的內置控件類型(如 QLabel
類),重寫不能影響到 ui 的控件。
但 Qt 也提供了解決方法,在 ui 界面對控件右鍵,選擇 提升為… 可以將控件的類型改變成自定義類型(前提是必須繼承了相關基類):
1. 處理鼠標事件
注意在重寫事件時,包含對應的頭文件,事件的函數不包含頭文件并不會找不到相關的函數,但其 event
參數一定會找不到它的任何方法。
1.1 enterEvent和leaveEvent
enterEvent 和 leaveEvent 分別表示鼠標進入控件和離開控件的事件。
1.2 mousePressEvent和mouseReleaseEvent
鼠標點擊左鍵、右鍵、滾輪、側鍵等都會觸發 mousePressEvent 和 mouseReleaseEvent 。如果想要確定究竟是哪些鼠標按鍵在觸發 mousePressEvent 或 mouseReleaseEvent ,Qt有 Qt::LeftButton
用來表示左鍵、Qt::RightButton
用來表示右鍵等,使用代碼用來判斷什么按鍵在觸發 mousePressEvent:
if(event->button() == Qt::LeftButton)
{qDebug()<<"按下左鍵";
}
else if(event->button() == Qt::RightButton)
{QDebug()<<"按下右鍵";
}
1.3 mouseDoubleClickEvent
當鼠標短時間兩次點擊時,就會觸發 mouseDoubleClicked(鼠標雙擊事件)。但當鼠標雙擊時,也是會觸發兩次 mousePressEvent 事件的,所以代碼中一定要做好單擊和雙擊的區別判斷,否則容易出現單雙擊同時觸發的 Bug。
注意 mouseDoubleClickEvent 和 mouseDoubleClickedEvent 事件都是存在的,不要把這兩個搞混了。
#include "label.h"
#include <QMouseEvent>Label::Label(QWidget* parent):QLabel(parent)
{}void Label::mousePressEvent(QMouseEvent *event)
{if(event->button()==Qt::LeftButton){qDebug()<<"點擊鼠標左鍵";}else if(event->button()==Qt::RightButton){qDebug()<<"點擊鼠標右鍵";}}void Label::mouseDoubleClickEvent(QMouseEvent *event)
{if(event->button()==Qt::LeftButton){qDebug()<<"雙擊鼠標左鍵";}else if(event->button()==Qt::RightButton){qDebug()<<"雙擊鼠標右鍵";}
}
1.4 mouseMoveEvent
mouseMoveEvent(鼠標追蹤事件),由于鼠標只是小幅度移動就會產生大量的 mouseMoveEvent 事件,對程序運行的流暢度有很大影響,Qt 的 widget 默認關閉了鼠標追蹤,所以即使重寫了 mouseMoveEvent 也不會有效果。要想讓鼠標追蹤生效,需要使用 this->setMouseTracking(true)
,將鼠標追蹤開啟。
1.5 wheelEvent
wheelEvent(滾動事件),鼠標每次進行滾輪操作時都會觸發這個事件,event 中有一個 delta()
會返回鼠標每次滾輪移動的值,向上為整數,向下為負數。
注意 wheelEvent 的頭文件是 #include <QWheelEvent>
,且 event
的類型為 QWheelEvent*
。
#include "label.h"Label::Label(QWidget* parent):QLabel(parent)
{}void Label::wheelEvent(QWheelEvent *event)
{qDebug()<<event->delta();
}
2. 鍵盤事件
2.1 keyPressEvent
keyPressEvent(鍵盤按鍵事件),當鍵盤上的按鍵被按下時就會觸發該事件,QShorcut
就是基于該事件來設置快捷鍵的,實際我們也可以通過改寫該事件的虛函數來實現快捷鍵的效果:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::keyPressEvent(QKeyEvent* event)
{if(event->key()==Qt::Key_A && event->modifiers()==Qt::ControlModifier){qDebug()<<"按下ctrl+A";}
}
注意普通按鍵是
event->key()
,Ctrl 是event->modifiers()
。
3. 定時器事件
3.1 QTimerEvent
QTimerEvent(定時器事件)是與定時器有關的事件, QTimer
類就是通過 QTimerEvent 實現的。每一個定時器都有一個定時器的 ID 標識符,在程序中,可以通過不同的 ID 管理不同的定時器,使用多定時器實現程序的多樣化。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTimerEvent>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);timerID=this->startTimer(1000);//成員變量}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::timerEvent(QTimerEvent* event)
{if(event->timerId()!=timerID){return;}int value=ui->lcdNumber->intValue();if(value<0){this->killTimer(this->timerID);return;}value-=1;ui->lcdNumber->display(value);
}
4. 窗口移動和大小變化事件
4.1 moveEvent
moveEvent(窗口移動事件),當窗口移動時就會觸發該事件,可以通過該事件實時獲取窗口此時的位置。
4.2 resizeEvent
resizeEvent(窗口大小變化事件),當窗口大小發生變化時就會觸發該事件,可以通過該事件動態調整控件大小。