我想要一个循环时间计数器来显示进程的剩余时间,如下图所示 我使用 Qty 6.6.3 和 Qty 小部件 如果有人有想法这样做,如果你能帮助我,我将不胜感激。
我写了类似于我想要的代码,但是这个模型正在加载,用户看不到剩余时间。
CircleLoadingWidget.cpp
#include <QtGui/qpainter.h>
#include <QtWidgets/qapplication.h>
#include "circle_loading_widget.h"
CircleLoadingWidget::CircleLoadingWidget(QWidget *parent)
: QWidget(parent)
, background(Qt::transparent)
, timerId(0)
{
}
CircleLoadingWidget::~CircleLoadingWidget()
{
}
void CircleLoadingWidget::setColors(const QList<QColor> &colors)
{
this->colors = colors;
if (timerId) {
update();
}
}
QColor CircleLoadingWidget::getColor(int i)
{
if (colors.size() > i) {
return colors.at(i);
} else {
switch (i) {
case 0:
return QColor("#dc322f");
case 1:
return QColor("#268bd2");
default:
return QColor("#90CAF9");
}
}
}
void CircleLoadingWidget::setBackground(const QBrush &background)
{
this->background = background;
if (timerId) {
update();
}
}
void CircleLoadingWidget::start()
{
if (!timerId) {
timerId = startTimer(1000 / 60);
timer.restart();
}
}
void CircleLoadingWidget::stop()
{
if (timerId) {
killTimer(timerId);
timerId = 0;
}
}
void CircleLoadingWidget::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
qint64 msecs = timer.elapsed();
msecs %= 5000;
bool inverted;
if (msecs > 2500) {
msecs = msecs - 2500;
inverted = true;
} else {
inverted = false;
}
QEasingCurve headCurve(QEasingCurve::OutQuart);
QEasingCurve tailCurve(QEasingCurve::InQuad);
QRect r0 = rect();
if (r0.width() > r0.height()) {
r0.setWidth(r0.height());
} else {
r0.setHeight(r0.width());
}
r0.moveCenter(rect().center());
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(background);
painter.setPen(background.color());
painter.drawRect(rect());
for (int i = 0; i < 1; ++i) {
qreal k1 = qMin(msecs / (1000.0 + 1000.0 / 10 * i), 1.0);
qreal k2 = qMin(msecs / (1500.0 + 1000.0 / 10 * i), 1.0);
if (qFuzzyCompare(k1, k2)) {
continue;
}
qreal headAngle, tailAngle, spanAngle;
if (inverted) {
headAngle = 90 - headCurve.valueForProgress(k1) * 360;
tailAngle = 90 - tailCurve.valueForProgress(k2) * 360;
} else {
headAngle = headCurve.valueForProgress(k1) * 360 + 90;
tailAngle = tailCurve.valueForProgress(k2) * 360 + 90;
}
spanAngle = tailAngle - headAngle;
QRect r1 = r0 ;
r1.setSize(r0.size() * (0.1 * (10 - i)));
r1.moveCenter(r0.center());
QRect r2 = r0;
r2.setSize(r0.size() * (0.1 * (9 - i) + 0.01));
r2.moveCenter(r0.center());
qreal l1 = 1.0 - headCurve.valueForProgress(k1);
qreal l3 = tailCurve.valueForProgress(k1);
qreal l2 = 1.0 - l1 - l3;
painter.setBrush(getColor(0));
painter.drawPie(r1, headAngle * 16, spanAngle * 16 * l1 * 0.9);
painter.setBrush(background);
painter.drawPie(r2, headAngle * 16, spanAngle * 16 * l1 * 0.9);
painter.setBrush(getColor(1));
painter.drawPie(r1, headAngle * 16 + spanAngle * 16 * l1, spanAngle * 16 * l2 * 0.9);
painter.setBrush(background);
painter.drawPie(r2, headAngle * 16 + spanAngle * 16 * l1, spanAngle * 16 * l2 * 0.9);
painter.setBrush(getColor(2));
painter.drawPie(r1, headAngle * 16 + spanAngle * 16 * (l1 + l2), spanAngle * 16 * l3 * 0.9);
painter.setBrush(background);
painter.drawPie(r2, headAngle * 16 + spanAngle * 16 * (l1 + l2), spanAngle * 16 * l3 * 0.9);
}
}
void CircleLoadingWidget::timerEvent(QTimerEvent *event)
{
if (event->timerId() != timerId) {
QWidget::timerEvent(event);
return;
}
update();
}
CircleLoadingWidget.h
#ifndef CIRCLELOADINGWIDGET_H
#define CIRCLELOADINGWIDGET_H
#include <QtCore/qtimer.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qeasingcurve.h>
#include <QtWidgets/qwidget.h>
class CircleLoadingWidget : public QWidget
{
Q_OBJECT
public:
explicit CircleLoadingWidget(QWidget *parent = nullptr);
virtual ~CircleLoadingWidget() override;
public:
void setColors(const QList<QColor> &colors);
void setBackground(const QBrush &background);
void start();
void stop();
protected:
virtual void paintEvent(QPaintEvent *event) override;
virtual void timerEvent(QTimerEvent *event) override;
private:
QColor getColor(int i);
private:
QList<QColor> colors;
QBrush background;
QElapsedTimer timer;
int timerId;
};
#endif // CIRCLELOADINGWIDGET_H
结果是这样的(有加载动画,用户看不到剩余时间和进程):
您得到的结果与第一张图像有很大不同,因此并不完全清楚您想要实现什么目标。实际上,对于第一张图片,我会执行以下操作:
class Gauge: public QWidget
{
public:
Gauge(QWidget *parent = nullptr)
: QWidget(parent)
{}
void setValue(int value)
{
if (value != m_value) {
m_value = qBound(0, value, 100);
update();
}
}
protected:
void paintEvent(QPaintEvent *event) override
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.fillRect(rect(), Qt::white);
int size = qMin(width(), height()) - 40;
QRectF rect(20, 20, size, size);
QPen pen(QColor::fromString("#eaeaea"), 20, Qt::SolidLine, Qt::RoundCap);
painter.setPen(pen);
painter.drawEllipse(rect);
pen.setColor(QColor::fromString("#4a62ad"));
painter.setPen(pen);
painter.drawArc(rect, 90 * 16, -m_value * 16 * 3.6);
painter.setPen(QColor::fromString("#333333"));
QFont font = painter.font();
font.setBold(true);
font.setPointSize(size / 5);
painter.setFont(font);
painter.drawText(rect, Qt::AlignCenter, QString::number(m_value) + "%");
}
private:
int m_value{0};
};
可能应该是这样的: