物联网
您现在所在的位置:首页>企业动态>物联网

Qt绘图之时钟

编辑:学到牛牛IT培训    发布日期: 2023-08-29 08:42:29  

·前言

Qt简介

Qt 由奇趣科技公司(Trolltech)的两位创始人于1990年着手开发,1995年发布Qt 1.0。2008年,奇趣科技被诺基亚公司收购,Qt也因此成为诺基亚旗下的编程语言工具。在智能手机的冲击下诺基亚大厦轰然倒塌,2012年将 Qt 转让给Digia公司。Digia 是一家总部位于芬兰的IT业务供应商,每天向全球数以百万的人提供通讯技术的及时解决方案,业务涉及电信、工业、贸易、金融等,客户包括诺基亚、索尼爱立信、惠普、甲骨文等全球一流企业。超过1200名研发精英分别位于芬兰、瑞典、爱沙尼亚、俄罗斯、中国等地为客户提供端到端的服务。

正文

准备

硬件:一台电脑

软件:(IDE)Qt Creator 4.5.0(Community)、(版本)Qt5.9.4

创建项目


1.png



点击“New Project”创建新项目


2.png


如上图所示选择之后点击左下角的choose


3.png


自定义项目名称和项目路径


4.png


选择引用(Qt的版本)


5.png


定义类名、头文件名和源文件名


6.png

选择默认


9.png


创建成功


需要的头文件

#include <QWidget> // QWidget 类是所有用户界面对象的基类

#include <QPaintEvent> // QPaintEvent 类包含绘制事件的事件参数。

#include <QPainter> // QPainter 类在小部件和其他绘画设备上执行低级绘画

#include <QPen> // QPen 类定义了 QPainter 应该如何绘制形状的线条和轮廓。

#include <QBrush> // QBrush 类定义了 QPainter 绘制的形状的填充模式

#include <QtMath> //这些函数是C或标准模板库中不可用的基本数学运算的部分方便定义

#include <QTimer> // QTimer 类提供重复和单次计时器。

#include <QDebug> // QDebug 类为调试信息提供输出流。

绘制表盘

首先我们要确定绘制表盘需要哪些参数,半径和Π?按照数学的逻辑来说确实没错,不过把它运用到计算机中还是需要有所改变才可以,表盘的制作需要用到void QPainter::drawEllipse(int x, int y, int width, int height)这个函数,这是一个过载功能。以给定的宽度和高度绘制由从 (x, y) 开始的矩形定义的椭圆。

绘制刻度盘

绘制刻度盘我们需要知道每次转动的角度是多少,时钟有12个大的刻度,每个大的刻度有5个小刻度,所有秒钟每秒转动的角度为360/60 = 6°。圆心所在竖线上方向为y轴正半轴,0°参考点为x轴正半轴,顺时针旋转。从12点处开始绘制,那么我们的基础仰角就是90° * 3 = 270°,接下来依次是276°、282°。

绘制指针

时钟的指针分为时针、分针和秒针,原理基本上一模一样, 时针我们将其看作是一个等腰三角形,底边在中心指针圆域中,顶点指向刻度,所以我们需要知道三个点的坐标才可以绘制出时针(三角形)。

流程

首先我们分别通过QTime::currentTime.hour、QTime::currentTime.minute、QTime::currentTime.second获取系统的时、分、秒然后再把值赋给Hs、Ms、Ss,如何实时更新时间呢?我们需要一个定时器QTimer值设为1000,表示每间隔1秒返回一次系统时间。

实现

头文件

#ifndef WIDGET_H

#define WIDGET_H


#include <QWidget>

#include <QPaintEvent>

#include <QPainter>

#include <QPen>

#include <QBrush>

#include <QtMath>

#include <QTimer>


#define Pai 3.14


class Widget : public QWidget

{

    Q_OBJECT


public:

    Widget(QWidget *parent = 0);

    ~Widget();

    void paintEvent(QPaintEvent *);//重写绘制事件函数

    void Init_Parameter();//初始化参数函数

    void Draw_Clock(QPainter *);//绘制时钟

    void Draw_Dial(QPainter *);//绘制刻度盘

    void Draw_Text(QPainter *);//绘制刻度值

    void Draw_Pointer(QPainter *);//绘制 指针


private:

    QTimer *timer;//定时器

    QPoint Center_pos;//时钟圆心坐标

    int R_Edge;//外圆半径

    int R_Inside;//内圆半径

    int R_Center;//中心小圆半径

    int R_Pointer;//中心指针圆半径

    int Div_Max = 12;//大刻度值

    int Div_Min = 5;//小刻度值

    float BaseAngle = 270;//仰角

    int Hs;//时

    int Ms;//分

    int Ss ;//秒


};


#endif // WIDGET_H


.cpp文件

#include "widget.h"

#include <QTime>

#include <QDebug>


Widget::Widget(QWidget *parent)

    : QWidget(parent)

{

    timer = new QTimer(this);

    connect(timer,SIGNAL(timeout()),this,SLOT(update()));//定时调用绘制事件函数

    timer->start(1000);//开启定时器



}


Widget::~Widget()

{


}


void Widget::paintEvent(QPaintEvent *)

{

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing);//设置抗锯齿

    Draw_Clock(&painter);

    painter.drawEllipse(Center_pos,R_Edge,R_Edge);

}


void Widget::Draw_Clock(QPainter *painter) //绘制时钟(刻度盘、刻度值、指针)

{

    Init_Parameter();

    Draw_Dial(painter);

    Draw_Text(painter);

    Draw_Pointer(painter);

}


void Widget::Init_Parameter()

{

    Center_pos = QPoint(this->width()/2,this->height()/2); 

    R_Edge = this->height()/2; 

    R_Inside = R_Edge-10;

    R_Center = 15;

    R_Pointer = 6;

    QTime Time = QTime::currentTime();//获取当前系统时间


    Hs=Time.hour();

    Ms=Time.minute();

    Ss=Time.second();

}


void Widget::Draw_Dial(QPainter *painter)

{

    painter->save();


    for(int Loop = 0; Loop <= Div_Max*Div_Min; Loop++)

    {

        float Angle = BaseAngle + (360 / (Div_Max * Div_Min))*Loop;

        int R = R_Inside-1;

        int x_start = Center_pos.x() + R * cos((Angle / 180) * Pai);

        int y_start = Center_pos.y() + R * sin((Angle / 180) * Pai);


        if(Loop % Div_Min == 0) //判断大小刻度

        {

            QPen pen(Qt::black);

            pen.setWidth(2);

            painter->setPen(pen);

            R = R_Inside-20;

        }

        else 

        {

            QPen pen(Qt::black);

            pen.setWidth(2);

            painter->setPen(pen);

            R = R_Inside-15;

        }


        int x_end = Center_pos.x() + R * cos((Angle / 180) * Pai);

        int y_end = Center_pos.y() + R * sin((Angle / 180) * Pai);


        painter->drawLine(QPoint(x_start,y_start),QPoint(x_end,y_end)); 

    }



    painter->restore();

}


void Widget::Draw_Text(QPainter *painter)

{

    painter->save();


    QPen qPen(Qt::black);

    qPen.setWidth(2);    

    painter->setPen(qPen);

    QFont qFont("楷体",14,QFont::Bold,false);

    painter->setFont(qFont);


    int Dial_Text = 12;

    for(int Loop = 0;Loop < Div_Max;Loop++)

    {

        if(Dial_Text >12 )

            Dial_Text = 1;

        int R = R_Inside-60;

        float Angle = BaseAngle + (360 / Div_Max )*Loop;

        int x = Center_pos.x() + R * cos((Angle / 180) * Pai);

        int y = Center_pos.y() + R * sin((Angle / 180) * Pai);


        painter->drawText(QRect(x-20,y-20,80,80),QString::number(Dial_Text++));

    }



    painter->restore();

}


void Widget::Draw_Pointer(QPainter *painter)

{

    painter->save();


    QBrush qBrush = QBrush(QColor(Qt::black));

    painter->setBrush(qBrush);

    QPen qPen(Qt::black);

    qPen.setWidth(2);    

    painter->setPen(qPen);

//绘制秒针

    float Angle = BaseAngle + (360 / (Div_Max * Div_Min))*Ss;

    float RightAngle = Angle + 90; 

    float LeftAngle = Angle - 90; 

    int R = R_Inside-1;

    int x_start = Center_pos.x() + R * cos((Angle / 180) * Pai);

    int y_start = Center_pos.y() + R * sin((Angle / 180) * Pai);


    R = R_Pointer-1;

    int x_end1 = Center_pos.x() + R * cos(RightAngle * 3.14 / 180); 

    int y_end1 = Center_pos.y() + R * sin(RightAngle * 3.14 / 180);

    int x_end2 = Center_pos.x() + R * cos(LeftAngle * 3.14 / 180); 

    int y_end2 = Center_pos.y() + R * sin(LeftAngle * 3.14 / 180);


    QPointF qTriangle_S[3] = {QPoint(x_start,y_start),QPoint(x_end1,y_end1),QPoint(x_end2,y_end2)};

    painter->drawPolygon(qTriangle_S,3);

//绘制分针

    Angle = BaseAngle + (360 / (Div_Max * Div_Min))*Ms;

    RightAngle = Angle + 90; 

    LeftAngle = Angle - 90; 

    R = R_Inside-60;

    x_start = Center_pos.x() + R * cos((Angle / 180) * Pai);

    y_start = Center_pos.y() + R * sin((Angle / 180) * Pai);


    R = R_Pointer-1;

    x_end1 = Center_pos.x() + R * cos(RightAngle * 3.14 / 180); 

    y_end1 = Center_pos.y() + R * sin(RightAngle * 3.14 / 180);

    x_end2 = Center_pos.x() + R * cos(LeftAngle * 3.14 / 180); 

    y_end2 = Center_pos.y() + R * sin(LeftAngle * 3.14 / 180);


    QPointF qTriangle_M[3] = {QPoint(x_start,y_start),QPoint(x_end1,y_end1),QPoint(x_end2,y_end2)};

    painter->drawPolygon(qTriangle_M,3);

//绘制时针

    Angle = BaseAngle + (360 / Div_Max)*Hs;

    RightAngle = Angle + 90; 

    LeftAngle = Angle - 90; 

    R = R_Inside-120;

    x_start = Center_pos.x() + R * cos((Angle / 180) * Pai);

    y_start = Center_pos.y() + R * sin((Angle / 180) * Pai);


    R = R_Pointer-1;

    x_end1 = Center_pos.x() + R * cos(RightAngle * 3.14 / 180); 

    y_end1 = Center_pos.y() + R * sin(RightAngle * 3.14 / 180);

    x_end2 = Center_pos.x() + R * cos(LeftAngle * 3.14 / 180); 

    y_end2 = Center_pos.y() + R * sin(LeftAngle * 3.14 / 180);


    QPointF qTriangle_H[3] = {QPoint(x_start,y_start),QPoint(x_end1,y_end1),QPoint(x_end2,y_end2)};

    painter->drawPolygon(qTriangle_H,3);


    painter->restore();

}

效果图


7.png


最后附上一首李白的将进酒供大家欣赏:

将进酒

君不见黄河之水天上来,奔流到海不复回。

君不见高堂明镜悲白发,朝如青丝暮成雪。

人生得意须尽欢,莫使金樽空对月。

天生我材必有用,千金散尽还复来。

烹羊宰牛且为乐,会须一饮三百杯⑨。

与君歌一曲,请君为我倾耳听。

钟鼓馔玉不足贵,但愿长醉不复醒。

古来圣贤皆寂寞,惟有饮者留其名。

陈王昔时宴平乐,斗酒十千恣欢谑。

主人何为言少钱,径须沽取对君酌。

五花马、千金裘,呼儿将出换美酒,与尔同销万古愁。


免费试学
课程好不好,不如实地听一听

封闭学习

2

1

联系我们

电话:028-61775817

邮箱:1572396657@qq.com

地址:成都市金牛区西城国际A座8楼

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
    物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

    扫一扫,免费咨询

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
    物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

    微信公众号

  • 物联网_物联网专题新闻_物联网IOT资讯-学到牛牛
物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

学一流技术,找高薪工作

物联网_物联网专题新闻_物联网IOT资讯-学到牛牛

7-24小时服务热线:

028-61775817

版权声明 网站地图

蜀ICP备2021001672号

课程问题轻松问