• 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);");
    }
    
    

    源码

    如需源码请在此下载
    或联系我

    skytrails@163.com

    ..... created by skytrails
  • 相关阅读:
    此刻,很想那些老朋友
    985工程介绍
    211工程介绍
    蓝牙耳机声音断断续续
    不支持用淋浴洗澡
    在HY买饭
    成长路上的六个W
    屎、洗脚水
    Ubuntu更换软件源
    视频流媒体服务器RTMP和RTSP区别是什么?如何区分?
  • 原文地址:https://www.cnblogs.com/skytrails/p/14448404.html
Copyright © 2020-2023  润新知