Qt 事件傳遞流程-事件處理器|事件分發器|事件過濾器

SAKURA12發表於2024-08-28

(總體傳遞流程圖見文章末尾)

自定義控制元件結構

自定義繼承於QLabel的控制元件類 PropagateLabel.h

自定義視窗 PropagateWidget

PropagateWidget中新增一個PropagateLabel標籤

 1 PropagateWidget::PropagateWidget(QWidget *parent) :
 2     QWidget(parent)
 3 {
 4     QVBoxLayout* verticalLayout=new QVBoxLayout(this);
 5     verticalLayout->setSpacing(0);
 6     verticalLayout->setContentsMargins(0,0,0,0);
 7 
 8     // 新增自定義標籤PropagateLabel
 9     lbl=new PropagateLabel(this);
10 //    lbl->setText(QString::fromUtf8("Qt事件-總結"));
11     lbl->setFrameShape(QFrame::Box);
12     lbl->setFixedHeight(50);
13     lbl->setAlignment(Qt::AlignCenter);
14     lbl->setStyleSheet("background-color:blue;color:white;font-size:25px");
15 
16     verticalLayout->addWidget(lbl);
17 }

事件處理器-指定控制元件的指定事件

在自定義控制元件PropagateLabel中重寫滑鼠點選事件 mousePressEvent

1 void PropagateLabel::mousePressEvent(QMouseEvent *ev)
2 {
3     qDebug()<<"PropagateLabel::mousePressEvent";
4 }

滑鼠點選控制元件,檢測到事件輸出相應資訊

在視窗PropagateWidget中重寫 mousePressEvent

1 void PropagateWidget::mousePressEvent(QMouseEvent *event)
2 {
3     qDebug()<<"PropagateWidget::mousePressEvent";
4 }

如果視窗檢測到滑鼠點選事件將會有相應輸出

在自定義控制元件中設定事件接收狀態為accept,則控制元件檢測到事件之後不會傳遞給父控制元件(PropagateWidget),此時點選標籤只有自定義控制元件的輸出,即父控制元件檢測不到事件

在自定義控制元件中設定事件接收狀態為ignore,則控制元件檢測到事件之後會傳遞給父控制元件(PropagateWidget),由輸出可以看出,自定義控制元件先檢測事件,然後傳遞給父控制元件,此時父控制元件能檢測到事件

如果沒有顯式指定事件接收狀態,則預設為accep,即省略ev->accept/ev->ignore,預設父控制元件檢測不到事件

事件分發器-event

事件分發器在事件處理器之前獲取事件

在自定義控制元件PropagateLabel中重寫event

1 bool PropagateLabel::event(QEvent *e)
2 {
3     if (e->type()==QEvent::MouseButtonPress) // 指定需要檢測的事件
4     {
5         qDebug()<<"PropagateLabel::event";
6     }
7     return QLabel::event(e); // 返回 把事件傳遞下去
8 }

由輸出順序可知,event先檢測到事件,然後傳遞給預設事件處理器

如果在if分支中return true,則只有event能檢測到事件

如果return false,則事件不會再被控制元件的預設事件處理器檢測到,直接傳遞給父控制元件

事件過濾器-eventFilter

在事件到達控制元件之前攔截事件

在視窗PropagateWidget中重寫事件過濾器

1 bool PropagateWidget::eventFilter(QObject *watched, QEvent *event)
2 {
3     if (watched==lbl && event->type()==QEvent::MouseButtonPress)
4     {
5         qDebug()<<"PropagateWidget::eventFilter";
6     }
7     return QWidget::eventFilter(watched,event);
8 }

在建構函式里為控制元件安裝事件過濾器

lbl->installEventFilter(this);

輸出順序可以看到事件過濾器最早獲取事件

最後一句 QWidget::eventFilter ,Qt裡的定義為直接return false,即最後一句等價於直接寫return false,事件會繼續傳遞下去

在if分支裡return true,則事件過濾器會攔截事件,不再傳遞下去

(總結)事件傳遞流程圖

相關文章