简述
Qt自带的示例中有一个是关于时钟,演示了如何用QPainter的转换和缩放特性来绘制自定义部件。其中主要包含了时针、分针的绘制,并不包含秒针。下面,我们在原示例的基础上进行扩展。
实现方式
由于时钟是妙级更新的,所以我们需要定时刷新,时钟则使用之前讲过的QPainter 2D图形来进行绘制。
- 使用QTimer定时刷新,设置超时时间为1000毫秒(1秒)。
- 绘制时钟,通过paintEvent()实现,包括:时针、分针、秒针、及面板、表盘等。
示例
效果
源码
首先,我们构造一个定时器QTimer,连接其超时信号timeout()到槽函数update(),当调用update()时,系统会自动通知当前界面进行重绘(paintEvent())。
MainWindow::MainWindow(QWidget *parent): CustomWindow(parent){...// 构造定时器,设置超时为1秒QTimer *timer = new QTimer(this);connect(timer, SIGNAL(timeout()), this, SLOT(update()));timer->start(1000);...}重写paintEvent(),用于绘制时钟。
void MainWindow::paintEvent(QPaintEvent *event){Q_UNUSED(event);// 时针、分针、秒针位置 - 多边形static const QPoint hourHand[3] = {QPoint(7, 8),QPoint(-7, 8),QPoint(0, -30)};static const QPoint minuteHand[3] = {QPoint(7, 8),QPoint(-7, 8),QPoint(0, -65)};static const QPoint secondHand[3] = {QPoint(7, 8),QPoint(-7, 8),QPoint(0, -80)};// 时针、分针、秒针颜色QColor hourColor(127, 0, 120);QColor minuteColor(0, 127, 127, 120);QColor secondColor(0, 160, 230, 120);int side = qMin(width(), height());QTime time = QTime::currentTime();QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 平移坐标系原点至中心点painter.translate(width() / 2, height() / 2);// 缩放painter.scale(side / 200.0, side / 200.0);// 绘制时针painter.setPen(Qt::NoPen);painter.setBrush(hourColor);painter.save();// 每圈360° = 12h 即:旋转角度 = 小时数 * 30°painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));painter.drawConvexPolygon(hourHand, 3);painter.restore();painter.setPen(hourColor);// 绘制小时线 (360度 / 12 = 30度)for (int i = 0; i < 12; ++i) {painter.drawLine(88, 0, 96, 0);painter.rotate(30.0);}// 绘制分针painter.setPen(Qt::NoPen);painter.setBrush(minuteColor);painter.save();// 每圈360° = 60m 即:旋转角度 = 分钟数 * 6°painter.rotate(6.0 * (time.minute() + time.second() / 60.0));painter.drawConvexPolygon(minuteHand, 3);painter.restore();painter.setPen(minuteColor);// 绘制分钟线 (360度 / 60 = 6度)for (int j = 0; j < 60; ++j) {if ((j % 5) != 0)painter.drawLine(92, 0, 96, 0);painter.rotate(6.0);}// 绘制秒针painter.setPen(Qt::NoPen);painter.setBrush(secondColor);painter.save();// 每圈360° = 60s 即:旋转角度 = 秒数 * 6°painter.rotate(6.0 * time.second());painter.drawConvexPolygon(secondHand, 3);painter.restore();}好了,注释写的很清楚了,就不多做讲解了,如果要做一个应用,可以自己实现一些设置指针、表盘样式外观的一些接口。
更多参考
- Analog Clock Example - 助手
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-08/133854.htm<!-- Baidu Button BEGIN -->