current position:Home>[Qt] Create a virtual clock dial to access system time (open source)

[Qt] Create a virtual clock dial to access system time (open source)

2022-11-24 23:07:39Evenurs

一、需求

Create a standalone window,It just shows a virtual clock,And keep consistent with the system time.

二、开始

2.1源文件

Find the source file of the image online,Sourced from Baidu Pictures.

 

 

 2.2创建窗口

 Note that the window size is consistent with the picture,Image background size:

三、代码

3.1毫秒定时器

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Timer1ms =startTimer(1);
}

3.2定时器事件

void MainWindow::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == Timer1ms)
    {
        QTime cQtime=QTime::currentTime();
        update();
    }
    else
    {
        ;
    }
}

3.3绘图事件

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;

    pix.load(_IMG_DISK);
    painter.drawPixmap(_DISK_X,_DISK_Y,_DISK_W*_COOR_COE,_DISK_H*_COOR_COE,pix);

    painter.translate(_DISK_W/2*_COOR_COE,_DISK_H/2*_COOR_COE);

    pix.load(_IMG_HOUR);
    painter.rotate(CT.GetAngleHour());
    painter.drawPixmap((_HOUR_X-_DISK_W/2)*_COOR_COE,
                       (_HOUR_Y-_DISK_H/2)*_COOR_COE,
                       _HOUR_W*_COOR_COE,
                       _HOUR_H*_COOR_COE,
                       pix);

    pix.load(_IMG_MIN);
    painter.rotate(CT.GetAngleMinute()-CT.GetAngleHour());
    painter.drawPixmap((_MINU_X-_DISK_W/2)*_COOR_COE,
                       (_MINU_Y-_DISK_H/2)*_COOR_COE,
                       _MINU_W*_COOR_COE,
                       _MINU_H*_COOR_COE,
                       pix);

    pix.load(_IMG_SEC);
    painter.rotate(CT.GetAngleSecond()-CT.GetAngleMinute());
    painter.drawPixmap((_SECO_X-_DISK_W/2)*_COOR_COE,
                       (_SECO_Y-_DISK_H/2)*_COOR_COE,
                       _SECO_W*_COOR_COE,
                       _SECO_H*_COOR_COE,
                       pix);

}

3.4Image positioning enumeration

typedef enum
{
    _DISK_X=0,
    _DISK_Y=0,
    _DISK_W=640,
    _DISK_H=640,

    _HOUR_X=281,
    _HOUR_Y=109,
    _HOUR_W=80,
    _HOUR_H=274,

    _MINU_X=308,
    _MINU_Y=84,
    _MINU_W=25,
    _MINU_H=281,

    _SECO_X=301,
    _SECO_Y=44,
    _SECO_W=38,
    _SECO_H=338,
}SOME_COOR;

3.5image source path

#define _IMG_DISK "E:/program/qt/timer/disk.png"
#define _IMG_HOUR "E:/program/qt/timer/hour.png"
#define _IMG_MIN "E:/program/qt/timer/minute.png"
#define _IMG_SEC "E:/program/qt/timer/second.png"

3.6缩放系数

#define _COOR_COE 1

3.7时间-Angle transformation instance declaration

CurrentTime CT;

3.8时间-Angle conversion function

void CurrentTime::CalculateAngle()
{
    double TempHour,TempSecond,TempMinute,TempMsec;

    AngleMsec=this->Msec/1000.0f*(double)360.0f;
    TempMsec=this->Msec;

    TempSecond=this->Second+TempMsec/1000.0f;
    AngleSecond=TempSecond*(double)6.0;

    TempMinute=this->Minute+TempSecond/60.0f;
    AngleMinute=TempMinute*(double)6.0;

    TempHour=this->Hour+TempMinute/60.0f;
    AngleHour=TempHour/(double)12.0*360.0;
}

四、效果

 Due to the high refresh rate of the timer,The rotation of the second hand is therefore continuous and smooth,If you need to design intermittent pause,Then change the timer interval to 1000,即1000ms即可.

五、总结

涉及知识点如下:

  1. 图片加载
  2. 定时器事件
  3. 画笔事件
  4. Time angle conversion
  5. 系统时间获取

For the path pit analysis of image loading failure, see the previous article:【Qt】关于在QtCreatorAn error is reported when using a file path in unknown escape sequence ‘\p‘问题解释_Evenurs的博客-CSDN博客

附录 源码

附录1、mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QTime>
#include "currenttime.h"

typedef enum
{
    _DISK_X=0,
    _DISK_Y=0,
    _DISK_W=640,
    _DISK_H=640,

    _HOUR_X=281,
    _HOUR_Y=109,
    _HOUR_W=80,
    _HOUR_H=274,

    _MINU_X=308,
    _MINU_Y=84,
    _MINU_W=25,
    _MINU_H=281,

    _SECO_X=301,
    _SECO_Y=44,
    _SECO_W=38,
    _SECO_H=338,
}SOME_COOR;
#define _COOR_COE 1
#define _IMG_DISK "E:/program/qt/timer/disk.png"
#define _IMG_HOUR "E:/program/qt/timer/hour.png"
#define _IMG_MIN "E:/program/qt/timer/minute.png"
#define _IMG_SEC "E:/program/qt/timer/second.png"
CurrentTime CT;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Timer1ms =startTimer(1000);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == Timer1ms)
    {
        QTime cQtime=QTime::currentTime();
        CT.RefreshTime(cQtime.hour(),cQtime.minute(),cQtime.second(),cQtime.msec());
        CT.CalculateAngle();
        update();
    }
    else
    {
        ;
    }
}
void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;

    pix.load(_IMG_DISK);
    painter.drawPixmap(_DISK_X,_DISK_Y,_DISK_W*_COOR_COE,_DISK_H*_COOR_COE,pix);

    painter.translate(_DISK_W/2*_COOR_COE,_DISK_H/2*_COOR_COE);

    pix.load(_IMG_HOUR);
    painter.rotate(CT.GetAngleHour());
    painter.drawPixmap((_HOUR_X-_DISK_W/2)*_COOR_COE,
                       (_HOUR_Y-_DISK_H/2)*_COOR_COE,
                       _HOUR_W*_COOR_COE,
                       _HOUR_H*_COOR_COE,
                       pix);

    pix.load(_IMG_MIN);
    painter.rotate(CT.GetAngleMinute()-CT.GetAngleHour());
    painter.drawPixmap((_MINU_X-_DISK_W/2)*_COOR_COE,
                       (_MINU_Y-_DISK_H/2)*_COOR_COE,
                       _MINU_W*_COOR_COE,
                       _MINU_H*_COOR_COE,
                       pix);

    pix.load(_IMG_SEC);
    painter.rotate(CT.GetAngleSecond()-CT.GetAngleMinute());
    painter.drawPixmap((_SECO_X-_DISK_W/2)*_COOR_COE,
                       (_SECO_Y-_DISK_H/2)*_COOR_COE,
                       _SECO_W*_COOR_COE,
                       _SECO_H*_COOR_COE,
                       pix);

}

 附录2、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    int Timer1ms;
    double AngleHour,AngleSec,AngleMin;
protected:
    void timerEvent(QTimerEvent *);
    void paintEvent(QPaintEvent *);
};
#endif // MAINWINDOW_H

附录3、currenttime.cpp

#include "currenttime.h"

CurrentTime::CurrentTime()
{
    Hour=0;
    Second=0;
    Minute=0;
    Msec=0;
}
void CurrentTime::RefreshTime(int hour,int min,int sec,int msec)
{
    this->Hour=hour;
    this->Minute=min;
    this->Second=sec;
    this->Msec=msec;
}
void CurrentTime::CalculateAngle()
{
    double TempHour,TempSecond,TempMinute,TempMsec;

    AngleMsec=this->Msec/1000.0f*(double)360.0f;
    TempMsec=this->Msec;

    TempSecond=this->Second+TempMsec/1000.0f;
    AngleSecond=TempSecond*(double)6.0;

    TempMinute=this->Minute+TempSecond/60.0f;
    AngleMinute=TempMinute*(double)6.0;

    TempHour=this->Hour+TempMinute/60.0f;
    AngleHour=TempHour/(double)12.0*360.0;
}
double CurrentTime::GetAngleHour()
{
    return this->AngleHour;
}
double CurrentTime::GetAngleMinute()
{
    return this->AngleMinute;
}
double CurrentTime::GetAngleSecond()
{
    return this->AngleSecond;
}
double CurrentTime::GetAngleMsec()
{
    return this->AngleMsec;
}

附录4、currenttime.h

#ifndef CURRENTTIME_H
#define CURRENTTIME_H


class CurrentTime
{
public:
    CurrentTime();
    void RefreshTime(int,int,int,int);
    void CalculateAngle();

    double GetAngleHour();
    double GetAngleMinute();
    double GetAngleSecond();
    double GetAngleMsec();
private:
    int Hour,Second,Minute,Msec;
    double AngleHour,AngleSecond,AngleMinute,AngleMsec;
protected:
};

#endif // CURRENTTIME_H

 

 

copyright notice
author[Evenurs],Please bring the original link to reprint, thank you.
https://en.chowdera.com/2022/328/202211242305595568.html

Random recommended