持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
今天为大家讲解一个小功能,使用Qt实现时钟。
这也是QtCreator示例中的一个小例子,不过示例中是使用QWindow实现的,现如今已经不使用了,首先我们先看下实现的效果吧!
在示例中采用的是QWindow窗口,一般在做项目开发时,多数情况下已经不采用QWindow窗口了,下面,我会用QWidget窗口来实现时钟效果。
时钟的组成部分:时针、分针、秒针
实现逻辑:使用定时器,每间隔一秒,刷新一次表盘显示,重绘绘制表盘显示。
实现难点:表盘绘制、时间针走向
那么,接下来我们具体来讲述如何实现一个时钟吧!
时钟窗口:宽度 = 高度 = 200
开发环境:VS2017 + Qt5.14.2
1:定时器设置刷新
定时器的设置在前面已经讲述很多次了,这里我们就简单概括下代码逻辑吧!
.h设置
protected:
virtual void timerEvent(QTimerEvent *event); //定时器
private:
int m_nTimerId; //定时器ID号
.cpp实现
//构造设置定时器触发
m_nTimerId = startTimer(1000);
void CustomAnalogClockWidget::timerEvent(QTimerEvent *event)
{
if (event->timerId() == m_nTimerId)
{
this->update();
}
QWidget::timerEvent(event);
}
每间隔一秒触发一次定时器,此时定时器中需要做刷新处理。
2:绘制时钟
绘制函数:paintEvent();
在绘制过程中,需要绘制的内容有以下几点:
1:绘制表盘刻度。包括了:时针刻度、分针刻度。
2:绘制时针、分针以及秒针的位置。
因为时间是在不断变化的,我们该如何绘制时针、分针以及秒针的位置呢?
在这里,我们要学习一个新的知识点:旋转(rotate)
原理:
根据绘制的时间不同,旋转不同的角度。
2.1:圆心设置
说到了旋转,最重要的第一步就是确定圆点,将widget窗口使用坐标轴标注。
对于坐标轴大家应该都不会陌生吧?这里我也就详细说明坐标轴了。
在程序中我们该如何设置这个中心点呢?
//定义widget中间点(100,100)为原点
painter.translate(width() / 2, height() / 2);
上文已经说到了,当前窗口的宽度,高度分别是200.
2.2:设置颜色值
时针颜色值:QColor crHour = QColor(127, 0, 127);
分针颜色值:QColor crMinute = QColor(0, 127, 127, 191);
秒针颜色值:QColor crSecond = QColor(128, 128, 0);
2.3:绘制分割线
绘制重点:旋转
设置:时针分割线
一天有12个小时,那么对应的时针分割线也应该是12条。在360°的圆盘中平均分割成12份,那么每次旋转的角度应该是30°。
我们在绘制过程中,一般情况下从正向坐标轴的0点开始绘制,如图
按照红色线条的走向进行设置。确定好第一条刻度线之后其它的也就根据角度旋转可以得到了。
//设置:时针分割线
painter.setPen(crHour);
for (int i = 0; i <12; i++)
{
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
展示效果,如下:
设置:分针分割线
1小时 = 60分钟,所以,时针的旋转角度应该是:6°
在绘制分针时有个特殊的位置,也就是当时针与分针的刻度值重合的位置。
//设置:分针分割线
painter.setPen(crMinute);
for (int j = 0; j < 60; j++)
{
if ((j%5) != 0)
{
painter.drawLine(92, 0, 96, 0);
}
painter.rotate(6.0);
}
展示效果,如下:
2.4:绘制时针、分针、秒针图形
简单期间,使用了三角形表示针的形状,这里大家可以自由发挥,为了美观,还可以设置带箭头的图形哦~
为了简单理解,在绘制过程中,我们只需要定义三针的初始位置,根据当前时间的不同,进行旋转就可以了。
时针、分针、秒针初始定义:
//定义:时针
static const QPoint ptHourHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -40)
};
//定义:分针
static const QPoint ptMinuteHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -70)
};
//定义:秒针
static const QPoint ptSecondHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -130)
};
计算时针的偏移角度:30.0 * ((time.hour() + time.minute() / 60.0))
计算分针的偏移角度:6.0*(time.minute() + time.second() / 60.0)
计算秒针的便宜角度:time.second()
时针绘制:
painter.setPen(Qt::NoPen);
painter.setBrush(crHour);
painter.save();
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(ptHourHand, 3);
painter.restore();
分针绘制:
painter.setPen(Qt::NoPen);
painter.setBrush(crMinute);
painter.save();
painter.rotate(6.0*(time.minute() + time.second() / 60.0));
painter.drawConvexPolygon(ptMinuteHand, 3);
painter.restore();
秒针绘制:
painter.setPen(Qt::NoPen);
painter.setBrush(crSecond);
painter.save();
painter.rotate(time.second());
painter.drawConvexPolygon(ptSecondHand, 3);
painter.restore();
到这里,时钟的重点绘制已经讲解完了,很简单的一个功能,重点就是学会如何旋转以及绘制设置。
我是中国好公民st,一名C++程序员