int main(int argc, char *argv[]) {QApplication a(argc, argv);MyWidget mainWidget;mainWidget.setWindowTitle("QObject與事件處理示例");mainWidget.resize(200, 200);mainWidget.show();return a.exec();
}
QApplication a(argc, argv);
:創建?QApplication
?對象,初始化應用程序的資源和事件循環。MyWidget mainWidget;
:創建?MyWidget
?類的實例,調用其構造函數。mainWidget.setWindowTitle("QObject與事件處理示例");
:設置窗口標題。mainWidget.resize(200, 200);
:設置窗口大小為 200x200 像素。mainWidget.show();
:顯示窗口。a.exec();
:啟動 Qt 的主事件循環,程序開始等待用戶輸入或系統事件。
2.?MyWidget
?構造函數部分
cpp
explicit MyWidget(QWidget *parent = nullptr) : QWidget(parent) {// 創建一個子對象(QLabel),父對象為MyWidgetQLabel *childLabel = new QLabel("點擊區域", this);childLabel->setObjectName("childLabel"); // 設置對象名稱用于過濾識別childLabel->setGeometry(50, 50, 100, 30);// 安裝事件過濾器到子控件childLabel->installEventFilter(this);
}
QLabel *childLabel = new QLabel("點擊區域", this);
:創建一個?QLabel
?子控件,顯示文本 “點擊區域”,并將?MyWidget
?作為其父對象。childLabel->setObjectName("childLabel");
:為?QLabel
?設置對象名稱,方便在事件過濾器中識別。childLabel->setGeometry(50, 50, 100, 30);
:設置?QLabel
?的位置和大小。childLabel->installEventFilter(this);
:為?QLabel
?安裝事件過濾器,將?MyWidget
?作為事件過濾器對象。
3. 事件處理部分
點擊?MyWidget
?非子控件區域
當用戶在?MyWidget
?的非子控件區域點擊鼠標左鍵時,會觸發?mousePressEvent
?函數:
cpp
void mousePressEvent(QMouseEvent *event) override {if (event->button() == Qt::LeftButton) {qDebug() << "[對象處理] 左鍵點擊位置:" << event->pos();event->accept(); // 阻止事件傳遞} else {QWidget::mousePressEvent(event); // 其他事件交由父類處理}
}
- 執行結果:控制臺會輸出點擊位置的信息,格式為?
[對象處理] 左鍵點擊位置: (x, y)
,其中?(x, y)
?是點擊位置的坐標。 - 事件流程:事件直接由?
MyWidget
?的?mousePressEvent
?函數處理,由于調用了?event->accept()
,事件不會繼續傳遞給父控件。
點擊?QLabel
?子控件區域
當用戶點擊?QLabel
?子控件時,事件會先經過事件過濾器:
cpp
bool eventFilter(QObject *watched, QEvent *event) override {if (watched->objectName() == "childLabel" && event->type() == QEvent::MouseButtonPress) {QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);qDebug() << "[事件過濾器] 子控件被點擊,全局坐標:" << mouseEvent->globalPos();return true; // 攔截事件,不再傳遞到子控件的mousePressEvent}return QWidget::eventFilter(watched, event); // 其他事件繼續傳遞
}
- 執行結果:控制臺會輸出子控件被點擊的全局坐標信息,格式為?
[事件過濾器] 子控件被點擊,全局坐標: (x, y)
,其中?(x, y)
?是全局屏幕坐標。 - 事件流程:事件被?
MyWidget
?的事件過濾器攔截,不會繼續傳遞到?QLabel
?的?mousePressEvent
?函數。
總結
- 當點擊?
MyWidget
?非子控件區域時,會觸發?mousePressEvent
?函數,輸出點擊位置信息并阻止事件傳遞。 - 當點擊?
QLabel
?子控件區域時,事件會先經過事件過濾器,輸出全局坐標信息并攔截事件,不會傳遞到?QLabel
?的?mousePressEvent
?函數。
編輯