当后台需要大量处理数据,前台要显示等待界面时,这个就很有用。
完全挡住界面上的内容,后面有半透明遮挡层,不能点击操作后面界面,用户不能自己取消等待界面,防止误操作。
并且窗口大小变化时,自动适应界面变化,不阻塞窗口移动和放大缩小,非模态的。
不是C#里面那种窗口截图的烂效果,真遮罩,真背景半透明。
需要配合多线程使用,前台显示等待界面,后台线程处理数据,当处理完毕,通过信号槽发消息通知前台取消等待状态。
补充:
有朋友问这个东西的源码怎么做出来的,下面贴出来:
1、新建一个Qt widget,类名为LoadingForm,带有ui界面的,在界面上放一个QLabel,调整到动画尺寸大小即可,用网格布局,居中显示。
2、LoadingForm的代码如下:
头文件LoadingForm.h:
#ifndef LOADINGFORM_H
#define LOADINGFORM_H
#include <QWidget>
namespace Ui {
class LoadingForm;
}
class LoadingForm : public QWidget
{
Q_OBJECT
public:
explicit LoadingForm(QWidget *parent = nullptr);
~LoadingForm();
private:
Ui::LoadingForm *ui;
};
#endif // LOADINGFORM_H
实现文件LoadingForm.cpp:
#include "loadingform.h"
#include "ui_loadingform.h"
#include <QMovie>
LoadingForm::LoadingForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::LoadingForm)
{
ui->setupUi(this);
this->setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
QMovie *movie;
movie = new QMovie(":/icon/res/loading.gif");
ui->label->setMovie(movie);
movie->start();
ui->label->setStyleSheet("background-color: transparent;");
}
LoadingForm::~LoadingForm()
{
delete ui;
}
3、在MainWindow上添加显示代码:
头文件内:
private:
QWidget* m_pMaskLayer = nullptr;
protected:
virtual void resizeEvent(QResizeEvent *event) override;
实现文件:
MainWindow6::MainWindow6(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow6)
{
ui->setupUi(this);
m_pMaskLayer = new LoadingForm(this);
m_pMaskLayer->setFixedSize(this->size());//设置窗口大小
m_pMaskLayer->setVisible(false);//初始状态下隐藏,待需要显示时使用
this->stackUnder(m_pMaskLayer);//其中pWrapper为当前窗口的QWidget
}
void MainWindow6::resizeEvent(QResizeEvent *event)
{
if(event){
}//消除警告提示
if(m_pMaskLayer != nullptr)
{
m_pMaskLayer->setAutoFillBackground(true); //这个很重要,否则不会显示遮罩层
QPalette pal = m_pMaskLayer->palette();
pal.setColor(QPalette::Background, QColor(0x00,0x00,0x00,0x20));
m_pMaskLayer->setPalette(pal);
m_pMaskLayer->setFixedSize(this->size());
}
}
//显示
void MainWindow6::showLoadingForm()
{
if(m_pMaskLayer != nullptr)
{
m_pMaskLayer->setVisible(true);
}
}
//隐藏
void MainWindow6::hideLoadingForm()
{
if(m_pMaskLayer != nullptr)
{
m_pMaskLayer->setVisible(false);
}
}
配合多线程,使用的时候直接showLoadingForm()和hideLoadingForm(),也可以自己添加全局信号槽实现。
注意:不能跟耗时操作混在UI线程,不然卡到没法用的。