網站首頁 編程語言 正文
1.Qt中事件的來源,誰接收處理。
Qt中事件的來源有兩個:程序外部和內部,多數情況下來自操作系統,可以通過bool QEvent::spontaneous() const函數來獲知,返回true,事件發生在應用程序之外(系統事件),否則返回false。
事件由QObject類來接收,是Qt對象模型的核心,所有需要處理的事件類都必須繼承QObject。
2.事件處理順序
首先QCoreApplication::exec()開啟了事件循環,一直到QCoreApplication::exit()被調用才終止,所以說事件循環是伴隨著Qt程序的整個運行周期,事件被分發到事件隊列中,當隊列中有事件時會不停的將事件發送給QObject對象,隊列為空時就阻塞,以下為處理順序。
- sendEvent:使用notify()函數直接將事件發送給接收者,發送事件時不會刪除該事件,通常是在棧上面創建事件,它是同步事件。
- postEvent:將事件添加到事件隊列中,并立即返回;事件必須在堆上分配,因為提交事件隊列將獲得事件的所有權,并在提交后刪除它。在事件發布后訪問該事件是不安全的,它是異步事件。
示例:
void Widget::on_pushButton_clicked()
{
QKeyEvent eventPress(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QApplication::sendEvent(ui->label, &eventPress);
}
void Widget::on_pushButton_2_clicked()
{
QKeyEvent *eventPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
QApplication::postEvent(ui->label, eventPress);
}
點擊上圖中按鈕會發送QLabel標簽的鍵盤按下tab鍵事件,我自定義了一個WLabel類繼承自QLabel,重寫了event方法。
bool WLabel::event(QEvent *e)
{
if(e->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = (QKeyEvent*)e;
if(keyEvent->key() == Qt::Key_Tab)
{
qDebug()<<"press tab key";
return ture;
}
}
return QLabel::event(e);
}
事件會發送到WLabel類的event方法中,會打印出下面的結果。
3.事件過濾器
事件的傳送和處理流程的第一站是事件過濾器eventFilter(),某個對象A可以通過給另一個對象B安裝事件處理器,實現對對象B事件的監聽或者攔截功能。我們可以給A取名監聽器,B取名接收器。一個對象可以監聽多個對象,一個對象也可以被多個事件監聽。事件過濾器返回true則表示事件已經處理完畢,否則傳遞給下一個監聽器或者接收器本身。
void QObject::installEventFilter(QObject *filterObj)
bool eventFilter(QObject *obj, QEvent *event);
Qt的事件過濾由以上兩個方法實現,首先安裝一個事件過濾器,然后重寫bool eventFilter(QObject *obj, QEvent *event)。
filterObj表示事件篩選器對象,它接收發送到此QObject對象的所有事件。篩選器可以停止事件,也可以將事件轉發給此QObject對象。事件過濾器filterObj通過它的eventFilter()函數接收事件。
eventFilter()有返回值。
- 如果返回true,表示事件過濾,不會發送到對象本身。
- 如果返回false,表示事件未過濾,會通過event()方法將事件分發到對象。
- 返回給基類進行處理,例:return QObject::eventFilter(obj, event)。
Qt 事件過濾器(秒懂)_Mr.codeee的博客-CSDN博客
4.event方法
當經過事件過濾器后,未過濾掉的事件會進入到event方法中,event()函數主要用于事件的分發。所以,如果你希望在事件分發之前做一些操作,就可以在派生類中重寫這個event()函數。
例:實現一些鼠標進出的打印,鍵盤按鍵一些打印。
bool WLabel::event(QEvent *e)
{
if(e->type() == QEvent::Enter)
{
qDebug()<<"WLabel event :enter";
return true;
}
else if(e->type() == QEvent::Leave)
{
qDebug()<<"WLabel event :Leave";
return true;
}
else if(e->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = (QKeyEvent*)e;
if(keyEvent->key() == Qt::Key_Tab)
{
qDebug()<<"press tab key";
return true;
}
}
return QLabel::event(e);
}
上述代碼中event如果事件e被識別并處理,則應返回true,否則交給它的基類QLabel來處理。
5.鼠標進入事件
bool WLabel::event(QEvent *e)
{
if(e->type() == QEvent::Enter)
{
qDebug()<<"WLabel event :enter";
}
return QLabel::event(e);
}
上述代碼,
- 如果事件返回return QLabel::event(e),會將鼠標進入事件分發到 enterEvent(QEvent *event),會打印下面的語句。
- 如果打印語句后面 return ture,則不會將事件傳遞到enterEvent中。
void WLabel::enterEvent(QEvent *event)
{
qDebug()<<"WLabel enterEvent";
}
6.accept(),ignore()
在我們做UI界面時,經常會重寫mousePressEvent,wheelEvent等函數,根據不同情況要對事件event進行特殊處理。
當執行event->accept()時,意味著這次的事件已經被“我”接受啦,只有我使用。
當執行event->ignore()時,意味著這次的事件“我”不要接受他,函數執行完event給我的父窗口,他會需要的。
差別也就是要不要傳遞給父窗口,accept不傳遞,ignore傳遞,注意是父窗口,不是基類。
原文鏈接:https://blog.csdn.net/wzz953200463/article/details/124259834
相關推薦
- 2023-04-07 C/C++浮點數使用的兩個注意事項詳解_C 語言
- 2022-02-04 Linux中查看進程命令ps aux,ps -ef,ps -A,ps -a
- 2022-04-21 詳解Golang?Map中的key為什么是無序的_Golang
- 2023-02-15 C#?9使用foreach擴展的示例詳解_C#教程
- 2022-06-27 Golang編程并發工具庫MapReduce使用實踐_Golang
- 2022-12-15 Oracle?listagg去重distinct的三種方式總結_oracle
- 2022-01-26 maatwebsite/Excel 導入 iconv (): Detected an illegal
- 2022-04-09 python中異常的傳播詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支