QT控件系列一 | 半透明遮罩弹窗

QT控件系列一 | 半透明遮罩(弹窗)

1.1 前言

​ 我们看Windows桌面应用,当你弹出一个提示弹窗,会发现弹窗有一个透明的遮罩,拖动遮罩应用界面跟随移动。这么设计一可以起到提示作用,二界面看起来很酷弦,三防止用户误操作。看下面的效果:

img

1.2 原理(技术点)

​ 今天我们用QT来实现这个功能,首先看下需要用到的技术点:

  • 无边框弹窗

    // 弹窗选择继承自QDialog
    class EShade : public QDialog{
      EShade(QWidget *parent){
        initStyle();
      }
      ~EShade();
    }
    
    // initStyle
    void initStyle() {
      setWindowFlags(Qt::FramelessWindowHint | windowFlags());// 去掉标题栏
      //TODO ADD CODE
      ...
    }
    
  • 半透明效果

    这个效果在网上查了有40%是用的paintEvent,还有59.99%用的是setWindowOpacity(0.2);我觉得这两种都不太好。前者太复杂,后者是对整个窗口实现半透明,包括了里面的子控件。这里介绍一种方便可控的方法:

    //不透明
    setStyleSheet("background: rgba(255, 255, 255, 1);");
    //半透明
    setStyleSheet("background: rgba(255, 255, 255, 0.5);");
    //全透明
    setStyleSheet("background: rgba(255, 255, 255, 0);");
    

全透明
不透明
半透明

PS:

​ 使用了setStyleSheet调成半透明后,子控件会继承父窗口的半透明效果,这时候只要在不需要半透明的位置放一个QFrame或者QLabel重新设置下背景色,并把子控件都放到QFrame/QLabel中。

  • 居中

    居中的实现方法很简单,计算好父窗口和需要居中的窗口大小,相减计算可得出位置,然后在构造函数中move到对应位置即可。

  • 同步主窗体

    这里要实现的是实现鼠标的拖动,并且弹窗移动了,父窗口也要跟随移动。

    这里用到QDialog的三个虛函数:

        // 鼠标按下事件
        virtual void mousePressEvent(QMouseEvent *event);
        // 鼠标移动事件
        virtual void mouseMoveEvent(QMouseEvent *event);
        // 鼠标释放事件
        virtual void mouseReleaseEvent(QMouseEvent *event);
    
    void EShade::mousePressEvent(QMouseEvent *event)
    {
        if(event->button() == Qt::LeftButton)
        {
            _bDrag = true;
            //获得鼠标的初始位置
            mouseStartPoint = event->globalPos();
            //获得窗口的初始位置
            windowTopLeftPoint = this->geometry().topLeft();
            parentTopLeftPoint = parentWidget()->frameGeometry().topLeft();
        }
    }
    
    void EShade::mouseMoveEvent(QMouseEvent *event)
    {
        if(_bDrag)
        {
            //获得鼠标移动的距离
            QPoint distance = event->globalPos() - mouseStartPoint;
            //改变窗口的位置
            this->move(windowTopLeftPoint + distance);
            parentWidget()->move(parentTopLeftPoint + distance);
        }
    }
    
    void EShade::mouseReleaseEvent(QMouseEvent *event)
    {
        if(event->button() == Qt::LeftButton)
        {
            _bDrag = false;
        }
    }
    
    

1.3 使用

MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)
  , ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  QPushButton *button = new QPushButton("弹出遮罩", this);
  button->show();
  QObject::connect(button, &QPushButton::clicked, [=]{
      EShade *shade = new EShade(this);
      shade->exec();
  });

  setStyleSheet("background: rgba(255, 255, 255, 1);");
}

1.4 资源下载

想要源码的可以在资源中下载
或联系我

skytrails@163.com

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值