头文件(Widget.h):
#ifndef CLOCK_H
#define CLOCK_H
#include <QWidget>
#include <QPainter>
#include <QTimer>
#include<QTime>
// 定义一个时钟类
class Clock : public QWidget
{
Q_OBJECT // 必须包含这一行(宏,由 MOC 编译器在编译时解释为 QObject 的数据成员和方法的描述。必须在类定义中包含,以便 MOC 能够生成必要的代码。)
public:
explicit Clock(QWidget *parent = nullptr);
protected:
void paintEvent(QPaintEvent *);
private:
// 设置时钟表盘直径为200像素
// const int clockDiameter = 200;
};
#endif // CLOCK_H
main.cpp
#include <QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);//创建一个 QApplication 对象,用于管理应用程序。
Clock w;
w.show();
return a.exec();//进入事件循环,等待事件的发生并及时处理,并且程序一直运行到结束。
}
Widget.cpp
#include "widget.h"
Clock::Clock(QWidget *parent) : QWidget(parent)//实现 Clock 类的构造函数,初始化时钟,并在每秒更新一次时钟。
{
// 每秒更新一次时钟
QTimer *timer = new QTimer(this);//创建一个 计时器对象。
connect(timer, SIGNAL(timeout()), this, SLOT(update()));//将 QTimer 对象的 timeout() 信号与 update() 槽连接。
timer->start(1000);//设置计时器以每秒触发一次。
}
void Clock::paintEvent(QPaintEvent *)//实现时钟绘制函数。
{
QPainter painter(this);//创建一个画师对象,用于在ui上进行绘制。
painter.setRenderHint(QPainter::Antialiasing); // 抗锯齿
// int side = qMin(width(), height()); // 获得较小的宽度或高度值,并作为边长。
// 将原点移动到窗口中心 (使画布居中)
painter.translate(width() / 2, height() / 2);
painter.scale(2, 2);
//painter.scale(side, side);// 缩放对象以适应窗口大小。
// 绘制表盘
painter.setPen(Qt::NoPen);//设置画笔为空。
painter.setBrush(Qt::white);//设置画刷为白色。
painter.drawEllipse(-100,-100, 200, 200);//# x, y 表示圆心坐标,r 表示半径 painter.drawEllipse(x - r, y - r, 2 * r, 2 * r)
// 绘制刻度
painter.setPen(Qt::black);//设置画笔为黑色。
for (int i = 0; i < 12; ++i) {//循环绘制时钟刻度
painter.drawLine(0, -90, 0, -100);//绘制刻度线条。
painter.rotate(360/12);//旋转画布,绘制下一个刻度。
}
// 绘制时针、分针和秒针
QTime time = QTime::currentTime();//获取当前时间。
painter.save();//保存画布状态。
// 以时针为例,计算时针所需旋转的角度并执行旋转操作,参数为时分秒数的和再乘以30(一小时30度)
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));//将当前时间转换成时针需要旋转的角度,并将画布旋转到相应的位置,使得时针能够正确地显示当前时间。
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::black);
// 绘制时针,以多边形方式绘制,坐标点依次为(-2,5)、(2,5)、(0,-80)
painter.drawPolygon(QPolygonF(QVector<QPointF>() << QPointF(-2, 5)//QVector<QPointF>() 创建一个空的 QPointF 类型的向量,表示多边形的顶点坐标列表。
<< QPointF(2, 5)//QPointF(x, y) 表示一个二维平面上的点,即 (x, y) 坐标。
<< QPointF(0, -90)));//<< 操作符将各个点依次添加到向量中,组成多边形的顶点列表。
painter.restore();// 恢复保存的画布状态
painter.save();
painter.rotate(6.0 * (time.minute() + time.second() / 60.0));//60分钟转360度,一分钟转6度
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::blue);
painter.drawPolygon(QPolygonF(QVector<QPointF>() << QPointF(-1, 5)
<< QPointF(1, 5)
<< QPointF(0, -92)));
painter.restore();
painter.save();
painter.rotate(6.0 * time.second());
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::red);
painter.drawPolygon(QPolygonF(QVector<QPointF>() << QPointF(-1, 5)
<< QPointF(1, 5)
<< QPointF(0, -95)));
painter.restore();
}
运行结果: