需求
- 执行耗时任务时,显示等待窗口,而不是盲等
- 耗时任务执行完毕后,等待窗口关闭
- 等待窗口只附着在父窗口,不影响其他窗口的操作
效果
![](https://img-blog.csdnimg.cn/6a3665daa932461387bfc6e34b153824.png)
代码实现
Loading.h
#pragma once
#include <QWidget>
#include <QVector>
#include <QImage>
class QTimer;
class Loading : public QWidget
{
Q_OBJECT
public:
explicit Loading(QWidget *parent, int timeout=30000);
protected:
void paintEvent(QPaintEvent* e);
void showEvent(QShowEvent* e);
private:
QTimer* m_timer;
int m_seq;
bool firstShow;
QVector<QImage> m_images;
};
Loading.cpp
#include "Loading.h"
#include <QPainter>
#include <QMessageBox>
#include <QTimer>
Loading::Loading(QWidget *parent, int timeout)
: QWidget{parent},
m_seq(0),
firstShow(true)
{
setWindowFlags(Qt::FramelessWindowHint);//无边框
setAttribute(Qt::WA_TranslucentBackground);//背景透明
this->resize(parent->geometry().size());
this->move(0, 0);
for (int i = 0; i < 8; ++i)
{
QString imgUrl = QString(":/resource/common_loading%1.png").arg(i);
m_images << QImage(imgUrl);
}
m_timer = new QTimer(this);
connect(m_timer, &QTimer::timeout, this, [&]{
this->update();
});
QTimer::singleShot(timeout, this, [this]{
this->close();
QMessageBox::warning(this, "warning", "waiting timeout!", QMessageBox::Ok);
});
}
void Loading::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
painter.setBrush( QBrush(QColor(100, 100, 100, 100)));
painter.drawRect(geometry());
QRect rect((width() - 50)/2, (height()-50)/2, 50, 50);
painter.drawImage(rect, m_images[m_seq++%8]);
}
void Loading::showEvent(QShowEvent *e)
{
if (firstShow){
m_timer->start(150);
firstShow = false;
}
}
调用代码
void MainWindow::on_pushButton_clicked()
{
Loading l(this);
l.show();
EventLoop el;
el.Exec([&]{
std::this_thread::sleep_for(std::chrono::milliseconds(50000));
});
}
资源文件
(1条消息) Loading等待窗口png资源文件-Javascript文档类资源-CSDN文库