自学内容网 自学内容网

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)!