Qt实现半透明背景(遮罩)

实现功能

有时候我们的程序可能会需要弹出一个对话框,为了美观这个对话框后面需要半透明的遮罩。本文使用QWidget实现了一个半透明的遮罩,可以设置遮罩的大小,颜色,透明度以及遮罩内要显示的对话框,遮罩能够随着中央对话框的显示而显示,对话框的隐藏而隐藏,效果如下:
在这里插入图片描述

遮罩MaskForm的实现

想法是将要显示的对话框安装事件过滤器MaskForm,MaskForm拦截对话框的QEvent::Show和QEvent::Hide两个事件,与对话框进行同步显示隐藏,并在MaskForm的ShowEvent事件中确定显示的位置,代码如下

#ifndef MASKFORM_H
#define MASKFORM_H

#include <QWidget>
#include <QApplication>

class MaskForm : public QWidget
{
    Q_OBJECT
public:
    explicit MaskForm(QWidget *parent = 0);
    ~MaskForm();

    /**
     * @brief 注册要显示在遮罩中的窗口
     * @param widget 要显示的窗口
     */
    void installWidget(QWidget *widget);

    /**
     * @brief 设置遮罩的颜色,透明度
     * @param color 遮罩颜色
     * @param opacity 透明度
     */
    void setMaskColor(const QColor &color, float opacity);

    /**
     * @brief 设置顶层窗口(覆盖窗口)
     * @param widget 顶层窗口
     */
    void setTopWidget(QWidget *widget);

private:
    void init();
    void showEvent(QShowEvent *event);
    bool eventFilter(QObject *watched, QEvent *event);

private:
    QWidget *m_topWidget;   //顶层窗口,设置遮罩大小
    QWidget *m_widget;      //遮罩中显示的窗口
};

#endif // MASKFORM_H

#include "MaskForm.h"

#include <QDebug>
#include <QGridLayout>

MaskForm::MaskForm(QWidget *parent)
    : m_widget(nullptr)
    , m_topWidget(nullptr)
    , QWidget(parent)
{
    init();
}

MaskForm::~MaskForm()
{
}

void MaskForm::installWidget(QWidget *widget)
{
    if (widget == nullptr) {
        return;
    }

    widget->installEventFilter(this);
    m_widget = widget;

    connect(m_widget, &QWidget::destroyed, this, [=](){
        m_widget = nullptr;
    });
}

void MaskForm::setMaskColor(const QColor &color, float opacity)
{
    if (!color.isValid()) {
        return;
    }

    QPalette palette = this->palette();
    palette.setColor(QPalette::Window, color);
    this->setPalette(palette);

    setWindowOpacity(opacity);
}

void MaskForm::setTopWidget(QWidget *widget)
{
    if (widget == nullptr) {
        return;
    }

    m_topWidget = widget;
}

void MaskForm::init()
{
    setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
    setMaskColor(QColor(245, 125, 0), 0.6f);

    m_topWidget = QApplication::activeWindow();
}

void MaskForm::showEvent(QShowEvent *event)
{
    Q_UNUSED(event);
    this->setGeometry(m_topWidget->geometry());
}

bool MaskForm::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == m_widget) {
        if (event->type() == QEvent::Show) {
            this->show();
        }

        if (event->type() == QEvent::Hide) {
            this->hide();
        }
    }

    return QObject::eventFilter(watched, event);
}

MaskForm的使用

//使用遮罩
void DownLoadListForm::on_btnCreate_clicked()
{
    MaskForm maskForm;
    CreateDownloadDialog dlg(&maskForm);//将遮罩设置为中央窗口的父窗口
    maskForm.installWidget(&dlg);//注册中央窗口,进行事件拦截

    dlg.exec();
}
  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值