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
函数。
编辑