Qt 遮罩层(Alt+Tab切换窗口后也不会失效)
结合刘大侠的遮罩层通用版和另外一个博主的做的遮罩层
maskwidget.h:
#ifndef MASK_WIDGET_H
#define MASK_WIDGET_H
#include <QDialog>
class MaskWidget : public QDialog
{
Q_OBJECT
Q_PROPERTY(QStringList names READ names WRITE setDialogNames DESIGNABLE true)
public:
//static MaskWidget *Instance();
explicit MaskWidget(QWidget* parent = nullptr);
void setMainWidget(QWidget* pWidget);
QStringList names() const;
void setDialogNames(const QStringList& names);
protected:
bool eventFilter(QObject *obj, QEvent *event);
private:
//~MaskWidget();
private:
// Ui::MaskWidget *ui;
QStringList m_listName{ QStringList() };
QWidget* m_pMainWidget;
//static MaskWidget* m_pSelf;
};
#endif // MASK_WIDGET_H
maskwidget.cpp:
#include "maskwidget.h"
#include <QEvent>
#include <qguiapplication.h>
MaskWidget::MaskWidget(QWidget *parent) : QDialog(parent)
{
m_pMainWidget = nullptr;
hide();
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowDoesNotAcceptFocus);
qApp->installEventFilter(this);
this->setObjectName("MaskWidget");
this->setStyleSheet(R"(QDialog#MaskWidget{background-color: rgba(0, 0, 0, 0.7);})");
}
void MaskWidget::setMainWidget(QWidget *pWidget)
{
this->resize(pWidget->size());
this->setParent(pWidget);
this->move(pWidget->x(), pWidget->y());
m_pMainWidget = pWidget;
}
void MaskWidget::setDialogNames(const QStringList& names)
{
if(m_listName == names)
{
return;
}
m_listName = names;
}
QStringList MaskWidget::names() const
{
return m_listName;
}
bool MaskWidget::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::Hide)
{
if(m_listName.contains(obj->objectName()))
{
hide();
}
return QObject::eventFilter(obj, event);
}
if (event->type() == QEvent::Show)
{
if (!m_listName.contains(obj->objectName()))
{
return QObject::eventFilter(obj, event);
}
if(Q_NULLPTR == m_pMainWidget)
{
return QObject::eventFilter(obj, event);
}
resize(m_pMainWidget->size());
show();
auto pWidget = dynamic_cast<QWidget*>(obj); //将object转换为普通QWidget
if (Q_NULLPTR == pWidget)
{
return QObject::eventFilter(obj, event);
}
pWidget->activateWindow();
pWidget->setFocus(Qt::ActiveWindowFocusReason);
stackUnder(pWidget); //将该窗口设置放到弹窗的下面
m_pMainWidget->stackUnder(this); //将主窗口设置放到该组件界面下方,就能够有一个比较清晰的层次关系
//下面是实现将弹窗的位置移动到主程序的正中间,在这边实现的目的是为了减少代码量,毕竟写代码能偷的懒还是一定要偷的
QRect screenGeometry = m_pMainWidget->geometry();
int x = screenGeometry.x() + (screenGeometry.width() - pWidget->width()) / 2;
int y = screenGeometry.y() + (screenGeometry.height() - pWidget->height()) / 2;
pWidget->move(x, y);
}
return QObject::eventFilter(obj, event);
}
使用方法:
1.在主窗体.h头文件定义
std::unique_ptr<MaskWidget> MaskWidget_; //使用智能指针,自动回收资源
2.主窗体.cpp文件:
在构造函数里面填入:
MaskWidget_ = std::make_unique<MaskWidget>();
MaskWidget_->setMainWidget(this->topLevelWidget());
MaskWidget_->setDialogNames(QStringList() << "frmA" <<"frmB"<<"frmC" ); //frmA,frmB,frmC 是显示遮罩的弹出的对话框的对象名.最好在每个对话框里面都调用setObjectName设置一下窗体的名称,这样将窗体名称添加到setDialogNames里面的队列当中.
原文地址:https://blog.csdn.net/becklee2011/article/details/144018084
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!