背景
有时候我们想自定义Qt控件(派生自QWidget
),实现类似Qt::Popup
属性的弹窗,同时避免Qt::Popup
属性所带来的***副作用***(阴影效果、鼠标事件透传)。
涉及技术
-
事件过滤器:
eventFilter()
-
窗体属性设置:
setWindowFlags()
、setAttribute()
(非必需,仅用于美化样式)
核心代码
-
ButtonMenu.cpp
ButtonMenu
类为自定义弹窗类,重写eventFilter()
方法,实现对外部控件的鼠标点击事件的过滤与处理。
// 此函数内部代码,仅作外观美化之用
void ButtonMenu::init()
{
setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
}
// 事件过滤器
bool ButtonMenu::eventFilter(QObject *obj, QEvent *e)
{
// 截获鼠标点击事件
if (e->type() == Qt::MouseButtonPress)
{
// 当鼠标点击事件的主体不是此弹窗时,就隐藏此弹窗
if (obj != this) hide();
}
// 调用父类同名事件,避免可能产生的bug
return QWidget::eventFilter(obj, e);
}
-
MainWindow.cpp
MainWindow.cpp
为程序主窗口,让它安装ButtonMenu
对象的事件过滤器,以实现鼠标点击事件的过滤。
// `_menuBtn`为`ButtonMenu`对象的指针
void MainWindow::init()
{
installEventFilter(_menuBtn);
}