【QT】自定义时钟控件

一、简述

在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

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值