QT 轻松实现半透明遮罩效果
一、背景有时候我们需要实现下面的半透明遮罩效果,以便突出子窗口。二、实现原理1.总共分为三层:主窗口(Form)、遮罩、显示窗口。2.主窗口的子窗口是遮罩,遮罩的子窗口是显示窗口。3.遮罩设置为无边框,以及颜色和透明度等。4.然后监控显示窗口事件,显示窗口显示,遮罩也跟着显示。关闭同理。...
·
一、背景
有时候我们需要实现下面的半透明遮罩效果,以便突出子窗口。
二、实现原理
1.总共分为三层:主窗口(Form)、遮罩、显示窗口。
2.主窗口的子窗口是遮罩,遮罩的子窗口是显示窗口。
3.遮罩设置为无边框,以及颜色和透明度等。
4.然后监控显示窗口事件,显示窗口显示,遮罩也跟着显示。关闭同理。
三、代码动态图下面
//遮罩头文件
class MaskForm : public QWidget
{
Q_OBJECT
public:
MaskForm(QWidget *parent = 0);
~MaskForm();
//注册要显示在遮罩中的窗口
void installWidget(QWidget *widget);
//设置遮罩颜色、透明度
void setMaskColor(const QColor &color,float opacity);
//设置顶层窗口
void setTopWidget(QWidget *widget);
private:
void init();
void showEvent(QShowEvent *event);
bool eventFilter(QObject *watched, QEvent *event);
private:
QWidget *m_topWidget; //顶层窗口,设置遮罩颜色、透明度
QWidget *m_widget; //遮罩中显示的窗口
};
//遮罩CPP文件
MaskForm::MaskForm(QWidget *parent)
: QWidget(parent)
,m_topWidget(nullptr)
,m_widget(nullptr)
{
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()
{
/*
Qt::FramelessWindowHint
1.产生一个无边框的窗口,无法移动和改变大小。
Qt::Tool
1.工具窗口,如果有父窗口,则工具窗口将始终保留在它的顶部。
2.默认情况下,当应用程序处于非活动状态时,工具窗口则消失。
*/
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
setMaskColor(QColor(0,0,0),0.6f);
//1.返回具有键盘输入焦点的顶级窗口,如果没有应用程序窗口具有焦点,则返回0.
//2.但是即使没有焦点,也可能有一个活动窗口。例如一个窗口没有小部件接收关键事件。
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就是遮罩本身
this->show();
}
if(event->type() == QEvent::Hide)
{
this->hide();
}
}
return QObject::eventFilter(watched, event);
}
//调用
void LoginDialog::on_pushButton_clicked()
{
MaskForm *maskForm = new MaskForm(this);
//设置遮罩的父窗口
maskForm->setTopWidget(this);
//构造显示窗口ToolTips
ToolTips *toolTips = new ToolTips();
//注册显示窗口,进行事件拦截(显示窗口开关,遮罩也跟着开关)。
maskForm->installWidget(toolTips);
toolTips->show();
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献7条内容
所有评论(0)