本文介绍在 Qt 编程中如何实现当鼠标点击弹窗外部区域时,该弹窗可以自动关闭的效果。
1. ActivationChange 事件
弹窗通过监听 Activation 改变事件,来判断自身是否还是当前的活动窗口,如果不是则关闭自身。
在 QWidget 里面重写 event,捕获 QEvent::ActivationChange 事件:
1 | bool UserCenterDlg::event(QEvent* e) { |
2. Qt::WA_NoMouseReplay 介绍
摘自 Qt 帮助文档:
Qt::WA_NoMouseReplay: Used for pop-up widgets. Indicates that the most recent mouse press event should not be replayed when the pop-up widget closes. The flag is set by the widget’s author and cleared by the Qt kernel every time the widget receives a new mouse event.
Qt::WA_NoMouseReplay 属性可以用来避免如下情况的发生:
在鼠标点击 Popup Widget 外部区域时,该 Widget 接收到自身的 Activation 状态发生改变,关闭自身,但在该 Widget 在关闭后,Qt 依然会将鼠标点击事件继续向下传递,从而窗口外区域下面的控件也会被点击。
由于 Qt::WA_NoMouseReplay 属性只对具有 Popup 属性的 Widget 起作用,因此只能使用 QWidget,不能使用 QDialog,并设置 Qt::Popup 属性。
1 | setWindowFlags(windowFlags() | Qt::Popup); |
何时设置 Qt::WA_NoMouseReplay 属性了?
重写 mousePressEvent,在鼠标按下事件发生时,设置 Qt::WA_NoMouseReplay 属性。
1 | void UserCenterDlg::mousePressEvent(QMouseEvent* e) { |
3. 自定义 closed 信号
QWidget 没有关闭信号,我们可以自定义关闭信号,该信号在 closeEvent 中触发。
1 | void UserCenterDlg::closeEvent(QCloseEvent* e) { |
限于政策原因,在您看到该文章时,博客可能已经关闭了评论功能🥺
您可以通过在 blog-comment 项目中提交Issue来间接地发表评论🍀