(總體傳遞流程圖見文章末尾)
自定義控制元件結構
自定義繼承於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,則事件過濾器會攔截事件,不再傳遞下去
(總結)事件傳遞流程圖