水波纹进度条——QT利用QPainter绘制
水波纹进度条是一种很有趣的进度显示效果,水波纹进度条具有独特的动态效果,能够吸引用户的注意力,让界面更加生动有趣。水波纹进度条通过波纹的扩散和逐渐填充的方式来表示进度,让用户一目了然地知道任务的进度状态。
水波纹进度条是一种很有趣的进度显示效果,水波纹进度条具有独特的动态效果,能够吸引用户的注意力,让界面更加生动有趣。水波纹进度条通过波纹的扩散和逐渐填充的方式来表示进度,让用户一目了然地知道任务的进度状态。
一、简述
本示例介绍一个Qt利用QPainter实现水波纹进度条的方法。自定义一个继承自QWidget的类,并在其中重写paintEvent方法进行绘制操作。通过使用QPainter的绘制方法和一些算法,可以实现动态的水波纹效果。
二、 设计思路
-
创建一个继承自QWidget的自定义控件,命名为WaterProcess。
-
在WaterProcess的构造函数中,初始化相关变量和属性,例如进度值、波浪高度、波浪速度等。
-
重写WaterProcess的绘制事件函数paintEvent(QPaintEvent *event)。
-
在paintEvent函数中,使用QPainter进行绘制。首先绘制外圈的背景框,然后根据当前进度值计算波浪的高度,并绘制波浪效果。
-
绘制波浪效果可以使用QPainter的drawPath函数,根据当前进度值计算波浪的高度和位置。可以使用QTimer来定时更新波浪的位置,实现波浪的动态效果。
-
在WaterProcess中提供一个公有函数setValue,用于设置进度值。在setValue函数中更新进度值,并调用update函数请求重绘。
三、效果
四、核心代码
1、头文件
#ifndef WATERPROCESS_H
#define WATERPROCESS_H
#include <QWidget>
#include <QtWidgets>
class WaterProcess : public QWidget
{
Q_OBJECT
public:
explicit WaterProcess(QWidget *parent = nullptr);
~WaterProcess(){}
void setUsedColor (const QColor color);
protected:
void paintEvent(QPaintEvent *ev);
private:
//画背景
void drawBg(QPainter *painter);
//画水波
void drawProcess(QPainter *painter);
//画文字
void drawValue(QPainter *painter);
public slots:
void setMinValue(int value);
void setMaxValue(int value);
void setValue(int v);
void setBorderWidth(int width);
void setWaterHeight(int height);
void start();
void stop();
void updateWave();
private:
int m_minValue; //最小值
int m_maxValue; //最大值
int m_value; //当前值
double m_borderWidth; //边框宽度
double m_waterHeight; //水波高度
double m_offset; //水波偏移量
QColor m_bgColor; //背景颜色
QColor m_borderColor; //边框颜色
QColor m_usedColor; //进度颜色
QColor m_textColor; //文字颜色
QTimer *m_timer; //水波定时器
};
#endif // WATERPROCESS_H
2、实现代码
#include "waterprocess.h"
#include <QDebug>
WaterProcess::WaterProcess(QWidget *parent)
: QWidget(parent)
{
m_minValue = 0;
m_maxValue = 100;
m_value = 30;
m_borderWidth = 10.0;
m_waterHeight = 0.05;
m_offset = 0.6;
m_bgColor = QColor(120, 120, 120);
m_borderColor = QColor(80, 80, 80);
m_usedColor = QColor(50, 205, 50);
m_textColor = QColor(255, 255, 255);
//波浪
m_timer = new QTimer(this);
m_timer->setInterval(100);
connect(m_timer, &QTimer::timeout, this, &WaterProcess::updateWave);
m_timer->start();
}
void WaterProcess::setUsedColor(const QColor color)
{
m_usedColor = color;
}
void WaterProcess::paintEvent(QPaintEvent *ev)
{
Q_UNUSED(ev)
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
//背景
drawBg(&painter);
//进度、水波
drawProcess(&painter);
//进度数字
drawValue(&painter);
}
void WaterProcess::drawBg(QPainter *painter)
{
int width = this->width();
int height = this->height();
int side = qMin(width, height) - m_borderWidth;
int startX = (width - side) * 0.5;
int startY = (height - side) * 0.5;
painter->save();
painter->setBrush(QBrush(m_bgColor));
if (m_borderWidth == 0) {
painter->setPen(Qt::NoPen);
} else {
QBrush brush(m_borderColor);
painter->setPen(QPen(brush, m_borderWidth, Qt::SolidLine));
}
painter->drawEllipse(startX, startY, side, side);
painter->restore();
}
void WaterProcess::drawProcess(QPainter *painter)
{
int width = this->width();
int height = this->height();
int side = qMin(width, height) - (2 * m_borderWidth); //直径
int startX = (width - side) * 0.5;
int startY = (height - side) *0.5;
int endX = startX + side;
int endY = startY + side;
double percent = (m_value * 1.0) / (m_maxValue - m_minValue);
double w = 2 * M_PI / endX;
double A = endY * m_waterHeight;
double k = endY * (1.0 - percent);
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(m_usedColor);
QPainterPath totalPath;
//加入圆形路径
totalPath.addEllipse(startX, startY, side, side);
//水波路径
QPainterPath water1;
QPainterPath water2;
water1.moveTo(startX, endY);
water2.moveTo(startX, endY);
m_offset += 0.6;
if (m_offset > (endX / 2)) {
m_offset = 0;
}
for(int i = startX; i < endX; i++) {
//第一条波浪Y轴
double waterY1 = (double)(A * qSin(w * i + m_offset)) + k;
//第二条波浪Y轴
double waterY2;
waterY2 = (double)(A * qSin(w * i + m_offset + (endX / 2 * w))) + k;
water1.lineTo(i, waterY1);
water2.lineTo(i, waterY2);
if (m_value == m_minValue) {
waterY1 = endY;
}
if (m_value == m_maxValue) {
waterY1 = startY;
}
}
//封闭
water1.lineTo(endX, endY);
water2.lineTo(endX, endY);
QPainterPath path;
QColor waterColor1 = m_usedColor;
waterColor1.setAlpha(100);
QColor waterColor2 = m_usedColor;
waterColor2.setAlpha(200);
//第一条波浪
path = totalPath.intersected(water1);
painter->setBrush(waterColor1);
painter->drawPath(path);
//第二条波浪挖去后的路径
path = totalPath.intersected(water2);
painter->setBrush(waterColor2);
painter->drawPath(path);
painter->restore();
}
void WaterProcess::drawValue(QPainter *painter)
{
painter->save();
int width = this->width();
int height = this->height();
int side = qMin(width, height) - m_borderWidth;
int startX = (width - side) * 0.5;
int startY = (height - side) * 0.5;
int fontSize = side / 4;
QFont font;
font.setFamily("华文彩云");
font.setPixelSize(fontSize);
font.setBold(true);
painter->setFont(font);
painter->setPen(Qt::white);
painter->drawText(QRectF(startX, startY, side, side), Qt::AlignCenter, QString("%1%").arg(m_value));
painter->restore();
}
void WaterProcess::setMinValue(int value)
{
m_minValue = value;
update();
}
void WaterProcess::setMaxValue(int value)
{
m_maxValue = value;
update();
}
void WaterProcess::setValue(int v)
{
m_value = v;
update();
}
void WaterProcess::setBorderWidth(int width)
{
m_borderWidth = width;
update();
}
void WaterProcess::setWaterHeight(int height)
{
m_waterHeight = height;
update();
}
void WaterProcess::start()
{
if (m_timer) {
m_timer->start();
}
}
void WaterProcess::stop()
{
if (m_timer) {
m_timer->stop();
}
}
void WaterProcess::updateWave()
{
update();
}
这样就可以实现一个简单的水波纹进度条效果。可以通过调整绘制波浪效果的参数和动画效果,来实现不同的水波纹进度条样式。根据需要可以添加其他功能,例如添加气泡动画效果等。
五、使用示例
以下是一个简单的示例代码,演示了如何在Qt中使用此控件:
ui设计
界面交互代码
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
ui->waterProcess2->setUsedColor(QColor(79, 175, 243));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_borderWidthSlider_valueChanged(int value)
{
ui->waterProcess1->setBorderWidth(value);
ui->waterProcess2->setBorderWidth(value);
}
void Widget::on_processSlider_valueChanged(int value)
{
ui->waterProcess1->setValue(value);
ui->waterProcess2->setValue(value);
}
总结一下,水波纹进度条是一种常见的进度条效果,它通过模拟水波纹的效果来表示进度。在Qt中,可以使用QPainter类来实现水波纹进度条。通过Qt的QPainter类,可以方便地实现水波纹进度条效果。关键是要理解绘制水波纹的原理,然后使用QPainter的相关函数来进行绘制。同时,使用Qt的定时器可以实现进度条的动态显示。通过良好的封装和设计,可以使得水波纹进度条的实现更加灵活和易于扩展。
谢谢您的阅读,希望本文能为您带来一些帮助和启发。如果您有任何问题或意见,请随时与我联系。祝您度过美好的一天!
六、源代码下载
更多推荐
所有评论(0)