一、简述
在QT中实现自定义的时钟控件并可以实现与本机时间同步。
二、实现效果
三、工程文件
四、代码实现
1、背景图设置(此步根据需要添加)
QPainter painter(this);
//设置一个背景图片
QPixmap map(":/smsn.jpg");
QRect q1(0,0,864,864);
QRect q2(0,0,width(),height());
painter.drawPixmap(q2,map,q1);
2、设置定时器,时间间隔为1000毫秒,并且将定时器时间与update函数关联为信号和槽,定时器每过一个时间间隔发送信号,update作为槽函数,接到信号后自动调用paintEvent函数进行重绘。
QTimer *timer = new QTimer(this);
timer->start(1000);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
3、为达到较好效果,需要将坐标原点从界面的左上角平移至界面中心,并进行缩放,使得绘制出的表盘位于界面中心且大小合适
painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);
painter.translate(width()/2,height()/2);//平移坐标系原点至界面中心点
painter.scale(side/300.0,side/300.0);//等比例缩放
4、分步依次将时钟的构成部分绘制出来(具体代码后面附上)
drawScale(&painter);//绘制刻度线
drawScaleNum(&painter);//绘制刻度值
drawHour(&painter);//绘制时针
drawMin(&painter);//绘制分针
drawSec(&painter);//绘制秒针
5、获取当前的时间
QTime time=QTime::currentTime();//获取本机当前时间
五、完整代码
头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
void paintEvent(QPaintEvent *event);
public:
Widget(QWidget *parent = nullptr);
~Widget();
void drawCrown(QPainter *painter);
void drawBg(QPainter *painter);
void drawScale(QPainter *painter);
void drawScaleNum(QPainter *painter);
void drawHour(QPainter *painter);
void drawMin(QPainter *painter);
void drawSec(QPainter *painter);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
源文件
- widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include<QTimer>
#include<QPainter>
#include<QtMath>
#include<QTime>
#include<QPixmap>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QTimer *timer = new QTimer(this);
timer->start(1000);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
}
void Widget::paintEvent(QPaintEvent*event)
{
Q_UNUSED(event);
QTime time=QTime::currentTime();//获取本机当前时间
int side=qMin(width(),height());
QPainter painter(this);
//设置一个背景图片
QPixmap map(":/smsn.jpg");
QRect q1(0,0,864,864);
QRect q2(0,0,width(),height());
painter.drawPixmap(q2,map,q1);
painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);
painter.translate(width()/2,height()/2);//平移坐标系原点至界面中心点
painter.scale(side/300.0,side/300.0);//等比例缩放
drawScale(&painter);//绘制刻度线
drawScaleNum(&painter);//绘制刻度值
drawHour(&painter);//绘制时针
drawMin(&painter);//绘制分针
drawSec(&painter);//绘制秒针
}
void Widget::drawScale(QPainter *painter)
{
int radius = 90;
painter->save();//进行保存
QPen pen;
QColor HourScaleColor(255,0,0,255);//设置小时刻度线
QColor MinScaleColor(255,153,18,255);//设置分刻度线
pen.setCapStyle(Qt::RoundCap);//设置画笔样式
for(int i=0;i<=60;i++)
{
if(i%5==0)
{
pen.setColor(MinScaleColor);
pen.setWidthF(1.5);
painter->setPen(pen);
painter->drawLine(0,radius-10,0,radius);
}
else
{
pen.setColor(HourScaleColor);
pen.setWidthF(0.5);
painter->setPen(pen);
painter->drawLine(0,radius-5,0,radius);
}
painter->rotate(6);//每画一条刻度线将整个界面转动6度
}
painter->restore();//进行复位
}
void Widget::drawScaleNum(QPainter *painter)
{
int radius = 70;
painter->save();
QColor HourNumColor(255,153,18,255);//设置小时刻度值的颜色
painter->setPen(HourNumColor);
double startRad = 60 * (M_PI / 180);
double deltaRad = 30 * (M_PI / 180);
for (int i = 0; i < 12; i++)
{
double sina = qSin(startRad - i * deltaRad);//确定刻度数字位置与坐标原点连线和x正方向的夹角
double cosa = qCos(startRad - i * deltaRad);
QString strValue = QString("%1").arg(i + 1);
double textWidth = fontMetrics().width(strValue);//获取刻度值数字的属性
double textHeight = fontMetrics().height();
int x = radius * cosa - textWidth / 2;//确定刻度值数字的位置
int y = -radius * sina + textHeight / 4;
painter->drawText(x, y, strValue);
}
painter->restore();
}
void Widget::drawHour(QPainter *painter)
{
QTime time=QTime::currentTime();
painter->save();
QPen pen;
QColor pointerHourColor(0,0,0,255);//设置时针颜色
pen.setCapStyle(Qt::RoundCap);
painter->setPen(pointerHourColor);//进行颜色填充
painter->setBrush(pointerHourColor);
QPolygon pts;
pts.setPoints(4,-3,8,3,8,2,-40,-2,-40);//设置时针点的坐标
painter->rotate(30.0*((time.hour()+time.minute()/60.0)));//根据当前时间确定时针应该转过的角度
painter->drawConvexPolygon(pts);//进行绘制
painter->restore();
}
void Widget::drawMin(QPainter *painter)
{
QTime time=QTime::currentTime();
painter->save();
QPen pen;
QColor pointerMinColor(0,0,255,255);//设置分针颜色
pen.setCapStyle(Qt::RoundCap);
painter->setPen(pointerMinColor);
painter->setBrush(pointerMinColor);
QPolygon pts;
pts.setPoints(4,-2,8,2,8,1,-60,-1,-60);
painter->rotate(6.0*(time.minute()+time.second()/60.0));
painter->drawConvexPolygon(pts);
painter->restore();
}
void Widget::drawSec(QPainter *painter)
{
QTime time=QTime::currentTime();
painter->save();
QPen pen;
QColor pointerSecColor(255,0,0,255);//设置秒针颜色
pen.setCapStyle(Qt::RoundCap);
painter->setPen(pointerSecColor);
painter->setBrush(pointerSecColor);
QPolygon pts;
pts.setPoints(3,-1,10,1,10,0,-70);
painter->rotate(6.0*time.second());
painter->drawConvexPolygon(pts);
painter->restore();
}
Widget::~Widget()
{
delete ui;
}
- main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
六、添加的资源文件
资源图片前缀为: /
参考:https://blog.csdn.net/feiyangqingyun/article/details/101050443