导航进度条通过其动态的视觉效果,不仅提供了任务进度的实时反馈,还增强了用户体验的流畅性和直观性。“进度”的设计方式多种多样,不同种类的运用需要根据具体场景来规划具体的进度方式,一般都要在清楚了解了每个方式的设计优势时,根据自身的产品定位,再去设计体验方式,这才是正确的设计方式与流程,然后再通过这些细节来提升产品的转化率,增加产品的趣味度方为良策。
一、简述
Qt实现导航进度条控件。进度条组件提供了一种直观的方式来显示任务的进度,让用户清晰地了解任务的完成情况。
二、实现的功能
1、可设置前景色/背景色/当前值前景色/当前值背景色
2、可设置最大步数及当前第几步
3、可设置导航标签队列文字信息
三、效果
四、核心代码
1、头文件
#ifndef NAVIGATIONPROGRESSBAR_H
#define NAVIGATIONPROGRESSBAR_H#include <QWidget>class NavigationProgressBarPrivate;
class NavigationProgressBar : public QWidget
{Q_OBJECTQ_PROPERTY(QStringList messageList READ messageList WRITE setMessageList CONSTANT)Q_PROPERTY(int step READ step WRITE setStep CONSTANT)Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor CONSTANT)Q_PROPERTY(QColor currentBackgroundColor READ currentBackgroundColor WRITE setCurrentBackgroundColor CONSTANT)Q_PROPERTY(QColor foregroundColor READ foregroundColor WRITE setForegroundColor CONSTANT)
public:explicit NavigationProgressBar(QWidget *parent = nullptr);~NavigationProgressBar();QSize sizeHint() const override;QSize minimumSizeHint() const override;void setMessageList(const QStringList &list);QStringList messageList() const;void setStep(const int step);int step() const;void setBackgroundColor(const QColor &color);QColor backgroundColor() const;void setCurrentBackgroundColor(const QColor &color);QColor currentBackgroundColor() const;void setForegroundColor(const QColor &color);QColor foregroundColor() const;protected:void paintEvent(QPaintEvent *event) override;private:void drawBackground(QPainter *painter, const bool ok);void drawText(QPainter *painter, const bool ok);QScopedPointer<NavigationProgressBarPrivate> d;
};#endif // NAVIGATIONPROGRESSBAR_H
2、cpp文件
#include "navigationprogressbar.h"#include <QPainter>
#include <QDateTime>class NavigationProgressBarPrivate{
public:NavigationProgressBarPrivate(QWidget *parent): owner(parent){for(int i=0; i<maxStep; i++)topInfo << QString("Step%1").arg(i+1);}QWidget *owner;QColor backgroundColor = QColor(80, 80, 80);QColor foregroundColor = QColor(254, 254, 254);QColor currentBackgroundColor = QColor(QLatin1String("#4da1ff"));int maxStep = 5;int step = 0;QStringList topInfo;QStringList dateList;
};NavigationProgressBar::NavigationProgressBar(QWidget *parent): QWidget(parent), d(new NavigationProgressBarPrivate(this))
{
}NavigationProgressBar::~NavigationProgressBar()
{
}QSize NavigationProgressBar::sizeHint() const
{return QSize(500, 100);
}QSize NavigationProgressBar::minimumSizeHint() const
{return QSize(300, 75);
}void NavigationProgressBar::setMessageList(const QStringList &list)
{d->topInfo = list;d->maxStep = list.size();update();
}QStringList NavigationProgressBar::messageList() const
{return d->topInfo;
}void NavigationProgressBar::setStep(const int step)
{if(d->step >= step || step > d->maxStep)return;int s = step - d->step;for(int i=0; i<s; i++)d->dateList.append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));d->step = step;Q_ASSERT(d->step == d->dateList.size());update();
}int NavigationProgressBar::step() const
{return d->step;
}void NavigationProgressBar::setBackgroundColor(const QColor &color)
{d->backgroundColor = color;update();
}QColor NavigationProgressBar::backgroundColor() const
{return d->backgroundColor;
}void NavigationProgressBar::setCurrentBackgroundColor(const QColor &color)
{d->currentBackgroundColor = color;update();
}QColor NavigationProgressBar::currentBackgroundColor() const
{return d->currentBackgroundColor;
}void NavigationProgressBar::setForegroundColor(const QColor &color)
{d->foregroundColor = color;update();
}QColor NavigationProgressBar::foregroundColor() const
{return d->foregroundColor;
}void NavigationProgressBar::paintEvent(QPaintEvent *event)
{QWidget::paintEvent(event);QPainter painter(this);painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);drawBackground(&painter, false);drawText(&painter, false);drawBackground(&painter, true);drawText(&painter, true);
}void NavigationProgressBar::drawBackground(QPainter *painter, const bool ok)
{//圆半径为高度一定比例,计算宽度,将宽度等分double w = width() / d->maxStep * 1.0;double h = height() / 3 * 1.0;double radius = qMin(w, h) / 2;double initX = 0;double initY = height() / 2.0;//逐个绘制连接线条initX = w / 2;int step = d->maxStep;int penWidth = radius / 4;QColor backgroundColor = d->backgroundColor;if(ok){step = d->step;penWidth = radius / 8;backgroundColor = d->currentBackgroundColor;radius = radius / 7 * 6;}QPen pen(backgroundColor);pen.setWidthF(penWidth);pen.setCapStyle(Qt::RoundCap);painter->setPen(pen);painter->setBrush(Qt::NoBrush);for (int i = 0; i < step - 1; i++) {painter->drawLine(QPoint(initX, initY), QPoint(initX + w, initY));initX += w;}if(ok && (d->step > 0) && (d->step < d->maxStep))painter->drawLine(QPoint(initX, initY), QPoint(initX + w / 2, initY));//逐个绘制圆initX = w / 2;painter->setPen(Qt::NoPen);painter->setBrush(backgroundColor);for (int i = 0; i < step; i++) {painter->drawEllipse(QPointF(initX, initY), radius, radius);initX += w;}//逐个绘制圆中的数字initX = w / 2;QFont font("Microsoft YaHei", radius);painter->setFont(font);painter->setPen(d->foregroundColor);painter->setBrush(Qt::NoBrush);for (int i = 0; i < step; i++) {QRect textRect(initX - radius, initY - radius, radius * 2, radius * 2);painter->drawText(textRect, Qt::AlignCenter, QString::number(i + 1));initX += w;}
}void NavigationProgressBar::drawText(QPainter *painter, const bool ok)
{double w = width() / d->maxStep * 1.0;double h = height() / 3.0;double initX = 0;double initY = 0;QColor color = ok? d->currentBackgroundColor: d->backgroundColor;painter->setFont(QFont("Microsoft YaHei", h / 4));painter->setPen(color);painter->setBrush(Qt::NoBrush);int step = ok ? d->step: d->maxStep;for (int i = 0; i < step; i++) {QRect textRect(initX, initY, w, h);painter->drawText(textRect, Qt::AlignCenter, d->topInfo.at(i));initX += w;}if(ok){initX = 0;initY = h * 2;for (int i = 0; i < step; i++) {QRect textRect(initX, initY, w, h);painter->drawText(textRect, Qt::AlignCenter, d->dateList.at(i));initX += w;}}
}
3、示例代码
下面是一个示例代码,演示了如何创建一个 NavigationProgressBar控件
#include "mainwindow.h"
#include "navigationprogressbar.h"#include <QtWidgets>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{NavigationProgressBar *nav = new NavigationProgressBar(this);QStringList topInfo;topInfo << "拍下商品" << "已付款" << "卖家发货" << "确认收货" << "评价";nav->setMessageList(topInfo);QSlider *slider = new QSlider(this);slider->setRange(0, 5);connect(slider, &QSlider::valueChanged, nav, &NavigationProgressBar::setStep);QWidget *widget = new QWidget(this);QHBoxLayout *layout = new QHBoxLayout(widget);layout->addWidget(nav);layout->addWidget(slider);setCentralWidget(widget);resize(850, 150);
}MainWindow::~MainWindow()
{
}
本示例演示了淘宝订单流程样式。控件自适应任何分辨率,可以自由调整自身大小以适应分辨率的改变,总步骤以及当前步骤都是自动计算占用区域比例,直接提供接口设置步骤对应的文字信息等,接口非常友好。
这个示例只是一个基本的实现,实际应用中可能需要更复杂的逻辑来处理实时更新和动画显示,如文字自适应大小等。
在设计技巧方面,主要思路如下:
1、清晰的反馈机制:采用直观的标签、百分比或其他可视化元素,使用户可以轻松识别任务的进行状态,建立用户对应用程序的信任度,并让他们感到更有控制权和参与感。
2、利用动画效果:动画效果如渐变、平滑过渡等,使进度条显得更富有生命力,提升用户体验,让进度的变化更为直观。
3、适配用户期望的颜色搭配:在UI设计中,色彩运用极为关键,通过适配用户期望的颜色搭配,增强进度条的吸引力和易用性。
谢谢您的阅读,希望本文对您有所启发。如果您还有任何问题或需要进一步帮助,请随时与我联系。祝您度过愉快的一天!