Qt 遮罩层,等待后台处理动画效果

当后台需要大量处理数据,前台要显示等待界面时,这个就很有用。

完全挡住界面上的内容,后面有半透明遮挡层,不能点击操作后面界面,用户不能自己取消等待界面,防止误操作。
并且窗口大小变化时,自动适应界面变化,不阻塞窗口移动和放大缩小,非模态的。
不是C#里面那种窗口截图的烂效果,真遮罩,真背景半透明。

需要配合多线程使用,前台显示等待界面,后台线程处理数据,当处理完毕,通过信号槽发消息通知前台取消等待状态。

补充:
有朋友问这个东西的源码怎么做出来的,下面贴出来:
1、新建一个Qt widget,类名为LoadingForm,带有ui界面的,在界面上放一个QLabel,调整到动画尺寸大小即可,用网格布局,居中显示。
Qt 遮罩层,等待后台处理动画效果_第1张图片
2、LoadingForm的代码如下:
头文件LoadingForm.h:

#ifndef LOADINGFORM_H
#define LOADINGFORM_H

#include 

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 

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线程,不然卡到没法用的。

你可能感兴趣的:(QT)