简述

Qt自带的示例中有一个是关于时钟,演示了如何用QPainter的转换和缩放特性来绘制自定义部件。

其中主要包含了时针、分针的绘制,并不包含秒针。下面,我们在原示例的基础上进行扩展。

实现方式

由于时钟是妙级更新的,所以我们需要定时刷新,时钟则使用之前讲过的QPainter 2D图形来进行绘制。

  1. 使用QTimer定时刷新,设置超时时间为1000毫秒(1秒)。
  2. 绘制时钟,通过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 - 助手

Qt之模拟时钟的更多相关文章

  1. Qt之自定义控件(开关按钮)Qt之模拟时钟

    http://blog.csdn.net/u011012932/article/details/52164289 http://blog.csdn.net/u011012932/article/det ...

  2. 模拟时钟(AnalogClock)和数字时钟(DigitalClock)

    Demo2\clock_demo\src\main\res\layout\activity_main.xml <LinearLayout xmlns:android="http://s ...

  3. 一个模拟时钟的时间选择器 ClockPicker

    最近开发的一个模拟时钟的时间选择器 ClockPicker,用于 Bootstrap,或者单独作为一个 jQuery 插件. 源代码托管在 GitHub 上: ClockPicker 最近项目中需要用 ...

  4. android脚步---数字时钟和模拟时钟

    时钟UI组件是两个非常简单的组件,分为Digitalclock  和Analogclock, main.xml文件,书中程序有问题,加了两个组件,一个Button和一个<Chronometer ...

  5. Java多线程之sleep方法阻塞线程-模拟时钟

    package org.study2.javabase.ThreadsDemo.status; import java.text.SimpleDateFormat; import java.util. ...

  6. css模拟时钟

    css模拟时钟 思路: 画时钟数字(x,y)坐标 x = x0 + r*cos(deg) y = y0 + r*sin(deg) 知识点: 创建元素: createElement 添加元素: appe ...

  7. 【CSS3】纯CSS代码实现模拟时钟,+js对时功能。

    使用CSS3纯代码来实现模拟时钟,及指针动画功能. 在这里主要使用到css3一些基本元素: border-radius:圆角边框,画圆形:表盘 Transform:变换,旋转,扭曲:刻度盘,指针形状 ...

  8. 模拟时钟(AnalogClock)

    模拟时钟(AnalogClock) 显示一个带时钟和分针的表面 会随着时间的推移变化 常用属性: android:dial 可以为表面提供一个自定义的图片 下面我们直接看代码: 1.Activity ...

  9. Windows下编程--模拟时钟的实现

    windows下编程--模拟时钟的实现: 主要可以分为几个步骤: (1)   编写按键事件处理(启动和停止时钟) (2)   编写时钟事件处理,调用显示时钟函数 (3)   编写显示时钟函数,要调用显 ...

随机推荐

  1. require或include相对路径多层嵌套引发的问题

    require或include相对路径多层嵌套引发的问题   php中require/include 包含相对路径的解决办法 在PHP中require,include一个文件时,大都是用相对路径,是个 ...

  2. File Checksum Integrity Verifier

    Microsoft (R) File Checksum Integrity Verifier V2.05 README file =================================== ...

  3. sql默认启动密码

    首先启动sqlplus输入用户名:sqlplus / as sysdba密码空缺如果用户被锁定,记得加上SQL> alter user dbsnmp account unlock; User a ...

  4. 利用CGLib实现动态代理实现Spring的AOP

    当我们用Proxy 实现Spring的AOP的时候, 我们的代理类必须实现了委托类的接口才能实现. 而如果代理类没有实现委托类的接口怎么办? 那么我们就可以通过CGLib来实现 package cn. ...

  5. iOS - Swift Foundation 框架

    前言 框架是由许多类.方法.函数和文档按照一定的逻辑组织起来的集合,以使研发程序更容易. Foundation 框架:为所有程序开发奠定基础的框架称为 Foundation 框架. Cocoa :是指 ...

  6. 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)

    问题分析 问题一:要求日志最好入库:但是,直接入库mysql确实扛不住,批量入库没有问题,done.[批量入库和直接入库性能差异] 问题二:批量入库就需要有高并发的消息队列,决定采用redis lis ...

  7. JS trim()方法使用

    JS trim()方法使用上有浏览器限制: 1.直接使用 string.trim() 浏览器版本限制:JavaScript Version 1.8  2.间接使用<即自己使用正则构造类trim的 ...

  8. Linux输入子系统(转)

    Linux输入子系统(Input Subsystem) 1.1.input子系统概述 输入设备(如按键,键盘,触摸屏,鼠标等)是典型的字符设备,其一般的工作机制是低层在按键,触摸等动作发生时产生一个中 ...

  9. JQuery Ajax 的简单使用

    简单判断用户名存在不存在,如果数据库存在此用户名,提示不能注册 前台代码如下: <!DOCTYPE html> <html lang="en"> <h ...

  10. sqlplus入门基础语句

    关于Oracle 首先Oracle一个数据库由若干个表空间组成,每个表空间由若干个数据文件(或设备)组成,每个数据文件由若干个盘区组成,每个盘区由若干个block组成.这是Oracle的物理结构. 逻 ...