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