开源一下自己写的QT对话框遮罩,功能:
1,遮罩自动触发
2,遮罩颜色、透明度、尺寸人为设置
3,通过单例模式,调用简单、安全
头文件maskwidget.h
#ifndef MASKWIDGET_H
#define MASKWIDGET_H
#include <QWidget>
class CMaskWidget : public QWidget
{
public:
static CMaskWidget* GetInstance();
static void UnInstance();
//! 设置被遮盖的控件
void SetMainWidget(QWidget *pWidgetMasked);
/*
* \brief: 设置触发遮盖动作的控件名字
*
* \param[in]: lstWidgetNames 控件名字数组
*/
void SetDialogNames(const QStringList &lstWidgetNames);
/*
* \brief: 设置透明度
*
* \param[in]: fOpacity 透明度 取值范围0-1 1: 完全透明; 0: 完全不透明
*/
void SetOpacity(float fOpacity);
protected:
virtual void paintEvent(QPaintEvent *event) override;
virtual void showEvent(QShowEvent* event) override;
virtual bool eventFilter(QObject *obj, QEvent *event) override;
private:
explicit CMaskWidget(QWidget* wgt = nullptr);
~CMaskWidget();
private:
static CMaskWidget* m_pMask;
QWidget* m_pDlgToBeMasked = nullptr;
QStringList m_lstNamesForDlgPrompt;
};
#endif // MASKWIDGET_H
实现文件maskwidget.cpp
#include "maskwidget.h"
#include <QMutex>
#include <QEvent>
#include <QPainter>
#include <QApplication>
CMaskWidget* CMaskWidget::m_pMask = nullptr;
CMaskWidget* CMaskWidget::GetInstance()
{
static QMutex s_Mutex;
if (nullptr == m_pMask)
{
QMutexLocker locker(&s_Mutex);
if (nullptr == m_pMask)
{
m_pMask = new CMaskWidget;
m_pMask->setAttribute(Qt::WA_DeleteOnClose);
}
}
return m_pMask;
}
void CMaskWidget::UnInstance()
{
static QMutex s_Mutex;
if (nullptr != m_pMask)
{
QMutexLocker locker(&s_Mutex);
if (nullptr != m_pMask)
{
delete m_pMask;
m_pMask = nullptr;
}
}
}
void CMaskWidget::SetMainWidget(QWidget *pWidgetMasked)
{
if (m_pDlgToBeMasked != pWidgetMasked)
{
m_pDlgToBeMasked = pWidgetMasked;
setGeometry(m_pDlgToBeMasked->geometry());
}
}
void CMaskWidget::SetDialogNames(const QStringList &lstWidgetNames)
{
if (m_lstNamesForDlgPrompt != lstWidgetNames)
{
m_lstNamesForDlgPrompt = lstWidgetNames;
}
}
void CMaskWidget::SetOpacity(float fOpacity)
{
setWindowOpacity(fOpacity);
}
void CMaskWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
painter.setBrush(QBrush(QColor(0, 0, 0, 125)));
painter.setPen(Qt::transparent);
QRect rect = this->rect();
rect.setWidth(rect.width());
rect.setHeight(rect.height());
QPainterPath painterPath;
painterPath.addRoundedRect(rect, 15, 15);
painter.drawPath(painterPath);
QWidget::paintEvent(event);
}
void CMaskWidget::showEvent(QShowEvent* event)
{
if (nullptr != m_pDlgToBeMasked)
{
//! 获取被遮盖的窗口的宽高
QRect rectDlgMasked = m_pDlgToBeMasked->geometry();
int nWidth = rectDlgMasked.width();
int nHeight = rectDlgMasked.height();
setGeometry(0, 0, nWidth, nHeight);
}
QWidget::showEvent(event);
}
bool CMaskWidget::eventFilter(QObject *obj, QEvent *event)
{
if (QEvent::Show == event->type())
{
if (m_lstNamesForDlgPrompt.contains(obj->objectName()))
{
this->setVisible(true);
}
}
else if (QEvent::Hide == event->type())
{
if (m_lstNamesForDlgPrompt.contains(obj->objectName()))
{
this->setVisible(false);
}
}
return QWidget::eventFilter(obj, event);
}
CMaskWidget::CMaskWidget(QWidget* wgt /* = nullptr */)
{
setWindowFlags(windowFlags()
| Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
}
CMaskWidget::~CMaskWidget()
{
m_lstNamesForDlgPrompt.clear();
}
调用方法
//! 添加遮罩
CMaskWidget* maskWidget = CMaskWidget::GetInstance();
maskWidget->setParent(this);
maskWidget->SetMainWidget(this);
maskWidget->SetDialogNames(QStringList() << "CBonusForNewUserDlg");
m_pDlgBonusForNewUser = new CBonusForNewUserDlg(this);
m_pDlgBonusForNewUser->installEventFilter(maskWidget);
其中,this指的是被遮盖的控件对象;m_pDlgBonusForNewUser指的是触发遮罩的控件对象,即m_pDlgBonusForNewUser一显示,就让遮罩弹出。
参考了大神feiyangqingyun(QQ:517216493)
使用过程中有问题,可以评论或者私信问我。