Qt/C++ 动态时钟(背景可切换)

5 篇文章 0 订阅

// ClockWidget.cpp

#include "ClockWidget.h"
#include <QPainter>
#include <QTimer>
#include <QtMath>
# include <QDebug>
ClockWidget::ClockWidget(QWidget *parent) : QWidget(parent) {
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, [=](){this->update();});
   timer->start(1000); // 更新频率为1秒
    m_background = QPixmap("clock_face.png"); // 从资源加载表盘背景图像
}

ClockWidget::~ClockWidget() {}

void ClockWidget::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate(width() / 2, height() / 2); // 将坐标原点移到中心

    int side = qMin(width(), height());
    QPixmap scaledBg = m_background.scaled(side, side, Qt::KeepAspectRatio, Qt::SmoothTransformation);
    painter.drawPixmap(-side / 2, -side / 2, scaledBg);

    int radius = side / 2;
    drawHands(painter, radius);
    drawNumerals(painter, radius);
    drawClockFace(painter, radius);
}

void ClockWidget::drawClockFace(QPainter &painter, int radius) {
    painter.setPen(QPen(Qt::white, 2)); // 设置刻度颜色和粗细

    // 绘制小时刻度
    for (int i = 0; i < 12; ++i) {
        painter.drawLine(0, -radius, 0, -radius + radius * 0.1);
        painter.rotate(30.0); // 30度一个小时
    }

    // 绘制分钟刻度
    painter.setPen(QPen(Qt::white, 1)); // 分钟刻度更细
    for (int j = 0; j < 60; ++j) {
        if (j % 5 != 0) { // 避免与小时刻度重叠
            painter.drawLine(0, -radius, 0, -radius + radius * 0.05);
        }
        painter.rotate(6.0); // 6度一分钟
    }
}

void ClockWidget::drawHands(QPainter &painter, int radius) {
    QTime time = QTime::currentTime();

    // 绘制时针
    painter.save();
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::darkGray);
    int hour = time.hour() % 12; // 将24小时制转换为12小时制
    double minute = time.minute();
    double hourAngle = (hour * 30.0) + (minute * 0.5); // 时针角度
    painter.rotate(hourAngle); // 从12点钟方向开始
    painter.drawConvexPolygon(QPolygon() << QPoint(-radius * 0.05, 0)
                              << QPoint(0, -radius * 0.5)
                              << QPoint(radius * 0.05, 0)
                              << QPoint(0, radius * 0.05));
    painter.restore();

    // 绘制分针
    painter.save();
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::gray);
    int minuteAngle = time.minute() * 6; // 每分钟6度
    painter.rotate(minuteAngle ); // 从12点钟方向开始
    painter.drawConvexPolygon(QPolygon() << QPoint(-radius * 0.03, 0)
                              << QPoint(0, -radius * 0.7)
                              << QPoint(radius * 0.03, 0)
                              << QPoint(0, radius * 0.03));
    painter.restore();

    // 绘制秒针
    painter.save();
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::red);
    int secondAngle = time.second() * 6; // 每秒6度
    painter.rotate(secondAngle ); // 从12点钟方向开始
    painter.drawConvexPolygon(QPolygon() << QPoint(-radius * 0.02, 0)
                              << QPoint(0, -radius * 0.9)
                              << QPoint(radius * 0.02, 0)
                              << QPoint(0, radius * 0.02));
    painter.restore();
}


void ClockWidget::drawNumerals(QPainter &painter, int radius) {
    QString numbers[] = {"12", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11"};
    painter.setPen(Qt::white);
    painter.setFont(QFont("Arial", radius / 15));

    for (int i = 0; i < 12; ++i)
    {
        double angle = 30 * i -92 ; // 将12调整到最上方
        double radian = qDegreesToRadians(angle);
        int x = radius * 0.8 * qCos(radian);
        int y = radius * 0.8 * qSin(radian);
        painter.drawText(x - 10, y-20, 20+radius / 15, 20+radius / 15, Qt::AlignCenter, numbers[i]);
    }


    // 显示中心下方的码表(日期和时间)
    QDateTime currentTime = QDateTime::currentDateTime();
    painter.setFont(QFont("Arial", radius / 20));
    painter.drawText(-radius / 2, radius / 2-40, radius, 20+radius / 15, Qt::AlignCenter, currentTime.toString("yyyy-MM-dd HH:mm:ss"));
}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

(机)(器)(视)(觉)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值