当前位置: 首页 > article >正文

动态时钟控件:Qt/C++ 项目代码解读

基于Qt的动态时钟控件项目。该项目展示了如何通过Qt的绘图系统绘制一个带有表盘背景、时针、分针、秒针、以及时间日期显示的时钟。同时,这个时钟控件支持背景切换,并且每秒钟刷新一次,实时显示当前时间。

项目结构与功能概述

该时钟控件主要通过 QPainterQWidget 上绘制,利用 QTimer 来定时更新显示内容,使得时针、分针和秒针随时间转动。此外,还展示了如何通过绘制多边形来生成不同的指针,以及如何将表盘背景和数字刻度正确地绘制到窗口上。
在这里插入图片描述

代码部分解读

下面是代码的详细解读,按功能逐步解释。

# include "ClockWidget.h"
# include <QPainter>
# include <QTimer>
# include <QtMath>
# include <QDebug>

首先,项目包括了必要的Qt模块:

  • QPainter:负责处理绘图的核心类。
  • QTimer:用于每秒更新时钟控件。
  • QtMath:提供数学函数,特别是角度到弧度的转换。
  • 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"); // 从资源加载表盘背景图像
}
  1. QTimer:每秒触发一次 timeout 信号,连接到控件的 update() 函数,从而刷新时钟界面,实现动态更新。
  2. m_background:使用 QPixmap 加载一个图像作为表盘背景。
paintEvent() 函数:绘制时钟界面
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);
}

paintEvent() 中,通过 QPainter 实现整个时钟界面的绘制。

  1. setRenderHint(QPainter::Antialiasing):开启抗锯齿,使绘图更平滑。
  2. translate(width() / 2, height() / 2):将原点平移到窗口的中心,便于以中心为参考绘制时钟。
  3. 背景图像缩放:使用 scaled() 将表盘背景缩放到合适大小,并使用平滑变换。

接下来,调用了三个函数:

  • drawHands():绘制时针、分针和秒针。
  • drawNumerals():绘制时钟上的数字刻度。
  • drawClockFace():绘制表盘刻度。
drawClockFace() 函数:绘制时钟刻度
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度一分钟
    }
}
  1. 绘制小时刻度:使用 rotate() 每次旋转 30 度,绘制 12 个小时刻度。
  2. 绘制分钟刻度:与小时刻度类似,分钟刻度每次旋转 6 度,但线条更短、更细,避免与小时刻度重叠。
drawHands() 函数:绘制时针、分针和秒针
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;
    double minute = time.minute();
    double hourAngle = (hour * 30.0) + (minute * 0.5); // 时针角度
    painter.rotate(hourAngle); 
    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();
    
    // 分针与秒针类似
}
  1. 绘制时针:时针的角度根据当前小时和分钟计算出来,通过 rotate() 旋转相应的角度后绘制时针形状。
  2. 分针和秒针:与时针类似,但角度基于分钟和秒钟进行计算,并使用不同的形状和颜色。
drawNumerals() 函数:绘制时钟上的数字
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 ; 
        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"));
}
  1. 绘制数字刻度:将数字 12-11 绘制到表盘上,利用三角函数将数字定位在合适的位置。
  2. 日期时间显示:在表盘中心下方显示当前的日期和时间。

总结

这个项目展示了如何在 Qt 中利用 QPainter 实现一个动态的时钟控件,并且实现了时钟背景的自定义功能。通过结合 QTimer 来定时更新界面,实现了秒针、分针、时针的动态变化。


http://www.kler.cn/news/334990.html

相关文章:

  • RIFE: Real-Time Intermediate Flow Estimation for Video Frame Interpolation
  • 记一次炉石传说记牌器 Crash 排查经历
  • 爬虫——XPath基本用法
  • 华为海思:大小海思的双轮驱动战略分析
  • 9个微服务最佳实践
  • 【汇编语言】寄存器(CPU工作原理)(二)—— 汇编指令的基础操作
  • JavaScript中的数组不改变原数组的方法
  • 论文翻译 | Language Models are Few-Shot Learners 语言模型是少样本学习者(中)
  • DNABERT: 一个基于 Transformer 双向编码器表征的预训练 DNA 语言模型
  • MySql数据引擎InnoDB引起的锁问题
  • 通信工程学习:什么是DQDB分布式队列双总线
  • Java体系中的异常
  • 新机配置Win11
  • Leetcode—139. 单词拆分【中等】
  • Qt源码阅读——事件循环
  • MQTTnet.Extensions.ManagedClient客户端连接
  • 【数据结构】双向链表(Doubly Linked List)
  • Spring Boot ⽇志
  • Stable Diffusion 常用大模型及其特点
  • 数据结构之树(3)