如何写一个简单的时钟表盘(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();
}