qt 实现点击按钮显示弹窗,再次点击按钮或点击弹窗之外的区域,弹窗消失。
LumenWidget
为主界面
setting_
为弹窗界面
tbn_map_setting
为点击按钮
弹窗界面要先设置如下属性
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint |
Qt::Dialog);
第一步
主界面增加事件过滤器
bool LumenWidget::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress) {
if (watched != setting_ && watched != ui->tbn_map_setting &&
!setting_->findChildren<QObject *>().contains(watched) &&
qobject_cast<QWidget *>(watched)) {
if (setting_->isVisible()) {
setting_->hide();
}
}
}
return QWidget::eventFilter(watched, event);
}
第二步
将此事件过滤器加入到全部控件中
在主界面的构造函数加入以下代码
//方式1:使用全局的qApp
qApp->installEventFilter(this);
或
//方式2:递归遍历实现
QQueue<QObject *> q;
q.enqueue(this);
while (!q.isEmpty()) {
auto tmp = q.dequeue();
tmp->installEventFilter(this);
if (tmp == setting_) {
continue;
}
for (auto tmp_child : tmp->children()) {
q.enqueue(tmp_child);
}
}
第三步
设置按钮点击槽函数,本文为tbn_map_setting
void LumenWidget::on_tbn_map_setting_clicked()
{
//设置弹窗的弹出位置为按钮左下角
auto p = ui->tbn_map_setting->mapToGlobal(
QPoint(0, ui->tbn_map_setting->height()));
setting_->setGeometry(p.x(), p.y(), ui->tbn_map_setting->width(),
ui->tbn_map_setting->height());
//实现点击按钮弹窗弹出,再次点击弹窗消失
if (setting_->isHidden()) {
setting_->show();
} else {
setting_->hide();
}
}