QT开发中文网

QT绘制倒计时圆环

以下是一个基于Qt的倒计时圆环绘制示例:

  1. 首先,我们需要在Qt中创建一个自定义小部件来实现倒计时圆环的绘制。为此,我们可以使用QPainter类进行绘制操作。
class CountdownWidget : public QWidget
{
public:
    CountdownWidget(QWidget *parent = nullptr);
    
protected:
    void paintEvent(QPaintEvent *event) override;
};
  1. 在paintEvent函数中,我们可以使用QPainter类的方法来实现倒计时圆环的绘制。首先,我们需要计算出圆环上每个刻度线对应的角度值,并将其转换为弧度值。然后,根据当前时间和目标时间之间的差距,确定当前进度所占用的角度,并将其转换为弧度值。最后,根据这些值来绘制圆环。
void CountdownWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    
    int side = qMin(width(), height());
    
    // 绘制背景
    painter.fillRect(rect(), Qt::black);
    
    // 计算刻度线角度
    const int numTicks = 60;
    const qreal deltaAngle = 360.0 / numTicks;
    const qreal halfDeltaAngle = deltaAngle / 2;
    
    QVector<QLineF> tickLines;
    for (int i = 0; i < numTicks; ++i) {
        QLineF tickLine(0, -side / 2 + 10, 0, -side / 2 + 20);
        tickLine.setAngle(i * deltaAngle);
        tickLines.append(tickLine);
    }
    
    // 绘制刻度线
    painter.save();
    painter.translate(width() / 2, height() / 2);
    painter.setPen(QPen(Qt::white, 3));
    for (int i = 0; i < numTicks; ++i) {
        painter.drawLine(tickLines[i]);
    }
    painter.restore();
    
    // 计算进度角度
    const int totalSeconds = m_targetTime.secsTo(QDateTime::currentDateTime());
    const qreal progressAngle = (360.0 / m_totalSeconds) * totalSeconds;
    
    // 绘制圆环
    painter.save();
    painter.translate(width() / 2, height() / 2);
    
    QRectF rect(-side / 2 + 30, -side / 2 + 30, side - 60, side - 60);
    
    QPainterPath path;
    path.addEllipse(rect);
    
    QPen pen(Qt::white, m_thickness);
    pen.setCapStyle(Qt::FlatCap);
    
    qreal startAngle = -90.0;
    
    if (progressAngle > halfDeltaAngle) {
        // 绘制进度条
        pen.setColor(m_progressColor);
        painter.setPen(pen);

        qreal endAngle = startAngle + qMin(progressAngle - halfDeltaAngle,
                                           static_cast<qreal>(360.0));

        QPainterPath progressPath;
        progressPath.arcMoveTo(rect, startAngle);
        progressPath.arcTo(rect, startAngle, endAngle - startAngle);

        painter.drawPath(progressPath);

        startAngle += progressAngle;

        if (startAngle < 360.0 - halfDeltaAngle) {
            // 绘制未完成部分
            pen.setColor(m_backgroundColor);
            painter.setPen(pen);

            QPainterPath remainderPath;
            remainderPath.arcMoveTo(rect, startAngle);
            remainderPath.arcTo(rect, startAngle, 360.0 - halfDeltaAngle - startAngle);

            painter.drawPath(remainderPath);
        }
    } else {
        // 绘制未完成部分
        pen.setColor(m_backgroundColor);
        painter.setPen(pen);

        qreal endAngle = startAngle + qMin(halfDeltaAngle - progressAngle,
                                           static_cast<qreal>(360.0));

        QPainterPath remainderPath;
        remainderPath.arcMoveTo(rect, startAngle);
        remainderPath.arcTo(rect, startAngle, endAngle - startAngle);

        painter.drawPath(remainderPath);

        startAngle += halfDeltaAngle;

        // 绘制进度条
        pen.setColor(m_progressColor);
        painter.setPen(pen);

        QPainterPath progressPath;
        progressPath.arcMoveTo(rect, startAngle);
        
        if (progressAngle > 0) {
            progressPath.arcTo(rect, startAngle,
                               qMin(progressAngle + halfDeltaAngle,
                                    static_cast<qreal>(360.0)) - startAngle);
            
            if (progressAngl > 360.0 - halfDeltaAngel) {
                pen.setColor(m_backgroundColor);
                painter.setPen(pen);

                QPainterpath remainderpath;
                remaindertath.arcMoveto(rect, 270.0)
                remaindertath.lineTo(-side / 2 +30,-side/2+30)
                remaindertath.lineTo(side /2-30,-side/2+30)

                 painterrawLine(side /2-20,-side/2+30, side /2-20,-side/2+10)
                painterrawLine(side /2-30,-side/2+20, side /2-10,-side/2+20)
                
            }
        } else {
            progressPath.arcTo(rect, startAngle,
                               halfDeltaAngle - qMax(progressAngle,
                                                    static_cast<qreal>(0.0)));
        }

        painter.drawPath(progressPath);

        startAngle += progressAngle + halfDeltaAngle;
    }
    
    painter.restore();
}
  1. 最后,我们需要设置倒计时的目标时间和总共需要的时间,并在每次更新计时器事件发生时重绘小部件。
CountdownWidget::CountdownWidget(QWidget *parent)
    : QWidget(parent)
{
    m_targetTime = QDateTime::currentDateTime().addSecs(60);
    m_totalSeconds = 60;
    m_thickness = 12;
    
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [this]() { update(); });
    timer->start(1000);
}

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    
    CountdownWidget widget;
    widget.show();
    
    return app.exec();
}

这样,我们就可以得到一个基于Qt的倒计时圆环绘制示例。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://qt.0voice.com/?id=2602

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?