欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

如何写一个简单的时钟表盘(qt)

程序员文章站 2022-05-28 21:52:05
...

一,效果展示
如何写一个简单的时钟表盘(qt)
二,代码部分
**(一)**这个表盘主要用到的是时间事件和绘画事件,时间事件主要就是要让 指针动起来,而绘画事件就是画表盘了,先展示一下头文件代码:

#ifndef DIALOG_H
#define DIALOG_H


#include <QDialog>


QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE


class Dialog : public QDialog
{
    Q_OBJECT


public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();
    void paintEvent(QPaintEvent *event);
    void timerEvent(QTimerEvent *event);
    int eventSID,eventMID,eventHID;
    qreal rotates=90,rotatem=90,rotateh=90;//指针刻度初始值
private:
    Ui::Dialog *ui;
};
#endif // DIALOG_H

先来看一下绘画事件函数,绘画事件里面细分为画指针,写数字,画刻度,以及背景图四个部分。背景图最简单就不用说了。
(1)画刻度部分
画刻度部分,这个有两种画法,一种是直接运用painter.rotate()函数来旋转一小段一小段的线来绘制,注意用painter.translate(width()/2,height()/2)函数将坐标原点设在表盘中心,这样方便于绘制时容易找坐标;另外一种画刻度的方法就利用3个隐形同心圆,在三个圆上取点连线,外面两个圆为短线,内圆和外圆画长线,这个隐形圆取点其实就是用圆的参数方程,代码里面看起来没有圆,但是自己内心明白是用了三个圆,代码如下:

 for(int i=0;i<60;i++)
    {
        if(i%5!=0)
        {
            painter.drawLine(300+223*cos(2*PI/60*i),300+223*sin(2*PI/60*i),300+208*cos(2*PI/60*i),300+208*sin(2*PI/60*i));
        }
        else
        {
            painter.drawLine(300+223*cos(2*PI/60*i),300+223*sin(2*PI/60*i),300+195*cos(2*PI/60*i),300+195*sin(2*PI/60*i));
        }
    }//我这里取点时,还没有将坐标原点转移,所以圆心坐标前面有个300(就是表盘圆心为(300,300)

(2)写数字部分
如果我们用painter.rotate()绘制,那么画出来的数字会是倾斜的,所以我们用另外一种方法,就是将写数字的那个点的坐标求出来,然后再写数字。求坐标的方法也很简单,直接利用圆的参数方程就可以了,在写数字时注意移动一下点的坐标,代码如下:

Q for(int i=1;i<=12;i++)
        {
            painter.drawText(180*cos(2*PI/12*(i-3))-10,180*sin(2*PI/12*(i-3))+10,QString("%1").arg(i));
        }

(3)画指针部分
画指针时,我们将指针简化为一个三角形,当然,你也可以将指针化成其他形状,方法相似,画三角形的方法如下:

	QPainterPath drawtriangle;
        drawtriangle.moveTo(-150,0);
        drawtriangle.lineTo(20,3);
        drawtriangle.lineTo(20,-3);
        painter.setBrush(Qt::red);//颜色填充
        painter.drawPath(drawtriangle);

指针绘画代码为:

//rotates,rotatem,rotateh,这三个参数分别为秒针,分针,时针的旋转刻度
//分针
 	painter.save();
        painter.rotate(rotatem);
        QPainterPath drawtriangle;
        drawtriangle.moveTo(-150,0);
        drawtriangle.lineTo(20,3);
        drawtriangle.lineTo(20,-3);
        painter.setBrush(Qt::red);
        painter.drawPath(drawtriangle);
        painter.restore();
//时针
        painter.save();
        painter.rotate(rotateh);
        QPainterPath drawtriangle1;
        drawtriangle1.moveTo(-80,0);
        drawtriangle1.lineTo(20,3);
        drawtriangle1.lineTo(20,-3);
        painter.setBrush(Qt::black);
        painter.drawPath(drawtriangle1);
        painter.restore();
        //秒针
        painter.save();
        painter.rotate(rotates);
        painter.drawLine(0,0,-180,0);//秒针这里我偷了点懒,直接用一根线代替
        painter.restore();
        
        painter.setBrush(Qt::yellow);
        painter.drawEllipse(-3,-3,6,6);//这个是相当于固定三根指针的东西
}

接下来看时间事件,时间事件主要就是改变指针的的旋转度数,即改变rotates,rotatem,rotateh,这三个值,代码如下:

void Dialog::timerEvent(QTimerEvent *event)
{
    if(event->timerId()==eventSID)
    {
        rotates+=0.3;
        if(rotates==360)rotates=0;
    }
    if(event->timerId()==eventMID)
    {
        rotatem+=0.1;
        if(rotatem==360)rotatem=0;
    }
    if(event->timerId()==eventHID)
    {
        rotateh+=0.01;
        if(rotateh==360)rotateh=0;
    }
    repaint();
}

这里我只是简单的画了一个表盘,如果想要时钟跟踪系统时间,只需要重写一下时间事件函数即可,可以创建QTime类型,并将其赋值为QTime中的currentTime() 方法所返回的系统当前时间【这个时间同样是一个QTime类型】
QTime类型下可以通过hour(),minute(),second() 方法分别获取该时间的时、分、秒数据,并该数据类型可以直接当做数来使用,然后根据这个值在里将rotates,rotatem,rotateh初始化为当前时间的刻度,就可以了。
cpp文件代码展示如下:

#include "dialog.h"
#include "ui_dialog.h"
#include<QPainter>
#include<QPixmap>
#include<QPoint>
#define PI 3.141592653589


Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
    eventSID=startTimer(50);
    eventMID=startTimer(1000);
    eventHID=startTimer(1200);
    resize(600,600);
}


Dialog::~Dialog()
{
    delete ui;
}
void Dialog::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPixmap map("://res/10471237_100630738000_2_mh1590305631259.jpg");
    QRect q1(0,0,679,683);
    QRect q2(0,0,width(),height());
    painter.drawPixmap(q2,map,q1);
    for(int i=0;i<60;i++)
    {
        if(i%5!=0)
        {
            painter.drawLine(300+223*cos(2*PI/60*i),300+223*sin(2*PI/60*i),300+208*cos(2*PI/60*i),300+208*sin(2*PI/60*i));
        }
        else
        {
            painter.drawLine(300+223*cos(2*PI/60*i),300+223*sin(2*PI/60*i),300+195*cos(2*PI/60*i),300+195*sin(2*PI/60*i));
        }
    }




        painter.setRenderHint(QPainter::Antialiasing,true);
        painter.translate(width()/2,height()/2);
        painter.setFont(QFont(0,11));
        for(int i=1;i<=12;i++)
        {
            painter.drawText(180*cos(2*PI/12*(i-3))-10,180*sin(2*PI/12*(i-3))+10,QString("%1").arg(i));
        }
        painter.save();
        painter.rotate(rotatem);
        QPainterPath drawtriangle;
        drawtriangle.moveTo(-150,0);
        drawtriangle.lineTo(20,3);
        drawtriangle.lineTo(20,-3);
        painter.setBrush(Qt::red);
        painter.drawPath(drawtriangle);
        painter.restore();


        painter.save();
        painter.rotate(rotateh);
        QPainterPath drawtriangle1;
        drawtriangle1.moveTo(-80,0);
        drawtriangle1.lineTo(20,3);
        drawtriangle1.lineTo(20,-3);
        painter.setBrush(Qt::black);
        painter.drawPath(drawtriangle1);
        painter.restore();


        painter.save();
        painter.rotate(rotates);
        painter.drawLine(0,0,-180,0);
        painter.restore();


        painter.setBrush(Qt::yellow);
        painter.drawEllipse(-3,-3,6,6);


}
void Dialog::timerEvent(QTimerEvent *event)
{
    if(event->timerId()==eventSID)
    {
        rotates+=0.3;
        if(rotates==360)rotates=0;
    }
    if(event->timerId()==eventMID)
    {
        rotatem+=0.1;
        if(rotatem==360)rotatem=0;
    }
    if(event->timerId()==eventHID)
    {
        rotateh+=0.01;
        if(rotateh==360)rotateh=0;
    }
    repaint();
}
相关标签: 笔记 qt c++