使用场景
在我们软件上有时候需要做一些耗时操作,这时界面上应该有明确的的显示表明耗时操作正在进行中,而Qt中并没有提供此类控件,那就自己造轮子吧。
效果展示
示例代码
1、头文件
#ifndef WAITANIMATION_H
#define WAITANIMATION_H
#include <QWidget>
#include <QPainter>
#include <QPen>
#include <QMouseEvent>
class WaitAnimation : public QWidget
{
Q_OBJECT
public:
WaitAnimation(QWidget *parent = nullptr);
~WaitAnimation();
QColor foreColor() const;
void setForeColor(const QColor &newForeColor);
quint32 interval() const;
void setInterval(quint32 newInterval);
signals:
void foreColorChanged();
void intervalChanged();
protected:
void paintEvent(QPaintEvent*) override;
void timerEvent(QTimerEvent*) override;
void drawPoints(QPainter*);
private:
QColor mForeColor;//前景色
Q_PROPERTY(QColor foreColor READ foreColor WRITE setForeColor NOTIFY foreColorChanged FINAL)
quint32 mInterval;//绘制间隔,毫秒
Q_PROPERTY(quint32 interval READ interval WRITE setInterval NOTIFY intervalChanged FINAL)
quint32 startIndex;//每次绘制的起始角度索引
const quint32 pointCounts = 16;//画n个圆点,每个圆之间的角度偏移为360/n度
};
#endif // WAITANIMATION_H
2、cpp文件
#include "waitanimation.h"
WaitAnimation::WaitAnimation(QWidget *parent)
: QWidget(parent),
mForeColor(QColor(255,102,102,255)),
mInterval(50),
startIndex(0)
{
//无边框、置顶
setWindowFlags(this->windowFlags()|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);
//设置窗口背景透明
setAttribute(Qt::WA_TranslucentBackground);
startTimer(mInterval);
}
WaitAnimation::~WaitAnimation() {}
void WaitAnimation::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.setPen(Qt::NoPen);
p.setRenderHint(QPainter::Antialiasing);
drawPoints(&p);
}
void WaitAnimation::timerEvent(QTimerEvent *)
{
startIndex %= pointCounts;
this->update();
startIndex++;
}
void WaitAnimation::drawPoints(QPainter *p)
{
p->save();
quint32 curWidth = this->size().width();
quint32 curHeight = this->size().height();
quint32 refSize = qMin(curWidth, curHeight);
quint32 radius = refSize/2;
quint32 pointDiameter = refSize/12;//画圆的直径,相对窗口的大小
//坐标原点移动到中间
p->translate(refSize/2, refSize/2);
//第一个圆相对坐标原点的偏转角度
p->rotate(startIndex * 360/pointCounts);
for(quint32 index = 0; index < pointCounts; index++)
{
p->setBrush(QColor(mForeColor.red(),mForeColor.green(),mForeColor.blue(),index*255/pointCounts));
p->rotate(360/pointCounts);//每画一个圆都偏转固定的角度
p->drawEllipse(radius - pointDiameter, 0 - pointDiameter/2, pointDiameter, pointDiameter);
}
p->restore();
}
QColor WaitAnimation::foreColor() const
{
return mForeColor;
}
void WaitAnimation::setForeColor(const QColor &newForeColor)
{
if (mForeColor == newForeColor)
return;
mForeColor = newForeColor;
emit foreColorChanged();
}
quint32 WaitAnimation::interval() const
{
return mInterval;
}
void WaitAnimation::setInterval(quint32 newInterval)
{
if (mInterval == newInterval)
return;
mInterval = newInterval;
emit intervalChanged();
}
3、使用示例
#include <QApplication>
#include "waitanimation.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
WaitAnimation w;
w.setGeometry(800,800,200,210);
w.show();
return a.exec();
}