QT 透明遮罩(弹窗)
1.1 前言
我们看Windows桌面应用,当你弹出一个提示弹窗,会发现弹窗有一个透明的遮罩,拖动遮罩应用界面跟随移动。这么设计一可以起到提示作用,二界面看起来很酷弦,三防止用户误操作。看下面的效果:
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