Qt之模拟时钟

简述

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 - 助手
时间: 2024-10-09 00:25:01

Qt之模拟时钟的相关文章

模拟时钟

1 #include <Windows.h> 2 #include <tchar.h> 3 #include <math.h> 4 typedef struct Time 5 { 6 int hour, min, sec; 7 }TimeStructure; 8 BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow); 9 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM

JS模拟时钟

<html> <head> <title>js模拟时钟</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body onLoad="setInterval(setTimeSpan,1000);"> <span style="fon

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

Demo2\clock_demo\src\main\res\layout\activity_main.xml 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 and

WPF模拟时钟制作

近日因为项目需求,所以才花了一个晚上的时间来学习和制作WPF模拟时钟.本想着参考网上的WPF模拟时钟控件,但多数过于简单.也有一些模拟时钟确实制作的非常精美,但使用了GDI+技术,而非我需要的WPF时钟控件.好了,下面给出我制作的WPF模拟时钟的运行截图吧: 色彩方面只是用了黑色,白色,蓝色等鲜明的颜色,看起来没有特别绚丽,当然,如果需要,可以设置成需要的绚丽的颜色等. 以下是该模拟时钟的XAML代码部分: 1 <Window x:Class="AnalogClockProject.Mai

纯js+html+css实现模拟时钟

前几天没事写的个模拟时钟,代码仅供小白参考,大神请自动绕过. 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>模拟时钟</title> 6 <style> 7 body { 8 margin: 0; 9 padding: 0; 10 } 11 12 #blockDial {

模拟时钟(AnalogClock)

显示一个带时钟和分针的表面 会随着时间的推移变化 常用属性: android:dial 可以为表面提供一个自定义的图片 下面我们直接看代码: 1.Activity //模拟时钟 public class AnalogClockActivity extends Activity { private TextView timeTextView; private Handler handler; protected void onCreate(Bundle savedInstanceState) {

WinForm学习 --简单的模拟时钟程序

今天学习GDI+,试着想写一个模拟时钟的小程序,原以为很简单实现:但其实还有些复杂,特别是利用三角函数的那部分,让我四处找资料恶补了一下高中数学才算弄清楚,现在就回顾一下这个程序吧. 程序的目的是要模拟出时钟的效果,那首先就是要画出这个时钟的样子.不考虑美观,一个时钟最简单的组成是一个圆形的表盘,三根直线代表的时针.分针和秒针. <img缺失> 看起来很简单吧,但要怎么样画呢?让我们一步一步来吧: 1.画表盘 Graphics g = this.CreateGraphics(); //创建一个

使用ivx制作模拟时钟的经验总结

之前的帖子里已经使用时间轴和轨迹实现了很多的效果,今天我们来做一个模拟时钟.主要思路是用一个作为表盘,三个矩形分别作为时针,分针和秒针,通过各自轨迹设置他们在同一时间轴下的转动圈数成一定比例关系. 1.表盘首先是添加椭圆组件,这里我们需要设置它的原点横纵坐标都是50%,这样椭圆组件的XY坐标就是它的中心店坐标,这个XY坐标在我们设置指针的时候也要用到.2.添加指针指针使用矩形来展示的,由于指针要绕着表盘的中心点旋转,所以我们要将矩形的坐标原点与椭圆的坐标原点设置在同一个位置.因此先设置矩形的原点

WIN32下的模拟时钟

#include <Windows.h> #include <math.h> #include <tchar.h> #include "resource.h" #define PI 3.1415926 BOOLEAN InitWindowClass(HINSTANCE hInstance, int nCmdShow); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI W