1背景介绍
widget开发中,避免不了使用类似网页的那种等待加载页面,该文档记录在Qt中基于widget开发方式中Loading页面的开发
2.基于Widget的方式制作Loading页面的三种方式
1.基于QLabel+QMovie方式,必须有Loading页的完整的gif图,需要美工合成
2.基于QPainter+Pixmap()的方式,相当于找一系列离散的Loading图,用定时器控制在合适的时候绘制其中某一张,顺序绘制出来的看起来就是一个Loading,这种方法比较简单(本文使用这种方法)
3.纯手工绘制图形和文本,再使用旋转坐标系的方式执行,一般不特殊处理这种绘制出来的效果比较差,因为整个Loading都是匀速运转的,放弃这种方法,很麻烦,又不好看
2.1 核心代码展示
本代码基于单独的Widget制作,后期如果需要使用,需要在designer中布局一个普通的QWidget对象,然后使用提升,便可以使用。
2.2头文件定义
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTimer>
#include <QPainter>
#include <QPaintEvent>
#include <QPixmap>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public:
void startLoading(); //启动定时器并显示Loading页面
void endLoading(); //关闭定时器并隐藏loading页面
protected:
void paintEvent(QPaintEvent *event) override;
private:
Ui::Widget *ui;
QTimer *mTimer;
QList<QPixmap> mPixmap; //保存loading图片的集合
quint8 mIndex = 0;
};
#endif // WIDGET_H
2.3源文件定义
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlag(Qt::FramelessWindowHint);
mTimer = new QTimer(this);
connect(mTimer,&QTimer::timeout,this,[=](){
mIndex++;
if(mIndex>49)
mIndex = 0;
update();
});
resize(320,320);
for(int i = 0; i < 50; i++){
mPixmap.push_back(QPixmap(QString(":/loading/%1.png").arg(i+1)));
}
startLoading();
move(1920+50,150); //为了截图方便,show在一个比较纯背景的地方
}
Widget::~Widget()
{
delete ui;
}
void Widget::startLoading()
{
if(!mTimer->isActive())
mTimer->start(40);
show();
}
void Widget::endLoading()
{
if(mTimer->isActive())
mTimer->stop();
hide();
}
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter Paint(this);
Paint.setRenderHints(QPainter::TextAntialiasing |QPainter::Antialiasing);
Paint.drawPixmap(QRect(0,0,320,320),QPixmap(mPixmap[mIndex]));
}
2.4源文件描述
- resize当前窗体为320*320,因为美工切的图是320px的图,因此重置窗体的大小为320px
for(int i = 0; i < 50; i++){mPixmap.push_back(QPixmap(QString(":/loading/%1.png").arg(i+1)));}
给容器中添加切好的图,图片名为1..2...3.png,便于使用代码插入
3.效果预览
小知识分享
1.设置窗体无背景,可以有两种方式,第一种
setAttribute(Qt::WA_TranslucentBackground);
的方式,第二种是使用样式setStyleSheet("background:transparent;")
来设置,一般前者是搭配QPainter绘制,后者可以让当前窗体的父窗体的背景透出来(不使用当前窗体的背景遮盖父窗体的背景),使用前者不加绘制,窗体会变黑窗
2.定时器的两种使用方式,第一种是实例化QTimer对象,之后startTimer(),在TimeOut中处理,第二种是直接在类内部startTime()启动定时器,返回当前启动的定时器的TimerId,记录该TimerId,在窗体析构时关闭定时器killTimer(TimerId)
有什么问题可以在线讨论,觉得有用帮忙点个赞吧!^ _ ^