用Qt做一个漂亮的时钟

做出来的时钟的效果图

时钟获取电脑时间,每秒动一次
在这里插入图片描述

时钟实现原理

钟表的实现需要设置定时器,定时器每隔一秒发送timeout()信号到QWidget::update()槽函数,update()槽函数将会重绘一次窗口,重写重绘事件函数paintEvent(QPaintEvent *event),根据获取的当前系统时间的时钟、分钟、秒钟重绘钟表的时针、分针、秒针。

实现步骤

新建工程

正常地新建一个工程,模板选择Qt Widgets Application,工程名任起,不要出现中文,Details中选择三种都可以,这里选择MainWindow在这里插入图片描述在这里插入图片描述

添加资源文件

先找到刚刚建好的工程文件夹,新建文件夹,并将用作时钟背景的图片保存在此文件夹中,注意文件夹和图片的名称都不要使用中文Pixiv画师 Sul作品 https://www.pixiv.net/artworks/81060761
在新建文件或项目中选择新建文件Qt Resourse File,在资源编辑器中Add Files将图片加入,并将资源路径复制到剪贴板,可以先粘贴到记事本中或word中以供备用在这里插入图片描述

将图片放入窗口

代码:

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPaintEvent>


QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE


class MainWindow : public QMainWindow
{
    Q_OBJECT


public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    
    void paintEvent(QPaintEvent * event);//绘图事件
    
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    setWindowTitle("Clock");//窗口标题
    setWindowIcon(QIcon("://jpg/Sul 01.jpg"));//资源路径
    resize(1200,1063);//参考图片分辨率
}


MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    QPixmap map("://jpg/Sul 01.jpg");//资源路径

    QRect q(0,0,1200,1063);//参考图片分辨率

    QRect q2(0,0,width(),height());

    painter.drawPixmap(q2,map,q);


}



效果图
在这里插入图片描述

绘制指针和表盘

代码:

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPen>
#include <QFont>
#include <QPaintEvent>


QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void paintEvent(QPaintEvent * event);

private:
    Ui::MainWindow *ui;

    static const QPoint hourHand[4];
    static const QPoint minuteHand[4];
    static const QPoint secondHand[4];
    QPen hourHandPen;
    QPen minuteHandPen;
    QFont font;

    void gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight);


protected:
     void drawClockDial(QPainter *painter);
};
#endif // MAINWINDOW_H

// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QRadialGradient>
#include <QPainterPath>




MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    setWindowTitle("Clock");
    setWindowIcon(QIcon("://jpg/Sul 01.jpg"));
    resize(1200,1063);

    font.setPointSize(16);//数字字号
    font.setFamily("华文行楷");
    font.setBold(false);//不加粗
    setFont(font);
}


MainWindow::~MainWindow()
{
    delete ui;
}

//指针初始位置指向0点,即y轴负方向
//通过确定四个点的位置,用drawConvexPolygon()函数绘制四边形
const QPoint MainWindow::hourHand[4] = {
    QPoint(10, 4),
    QPoint(0, -15),
    QPoint(-10, 4),
    QPoint(0, -65)
        };


const QPoint MainWindow::minuteHand[4] = {
    QPoint(6, 5),
    QPoint(0, -20),
    QPoint(-6, 5),
    QPoint(0, -120)
        };


const QPoint MainWindow::secondHand[4] = {
    QPoint(4, 5),
    QPoint(0, 20),
    QPoint(-4, 5),
    QPoint(0, -180)
        };


void MainWindow::drawClockDial(QPainter *painter)
{
    QPen pen1;
    pen1.setWidth(4);//笔宽
    pen1.setColor(qRgb(204,197,193));//笔的颜色
    hourHandPen = pen1;

    QPen pen2;
    pen2.setWidth(2);
    pen2.setColor(qRgb(220,195,195));
    minuteHandPen = pen2;

     for (int i = 1; i <=60; ++i)
    {
        painter->save();
        painter->rotate(6*i);
        if (i % 5 == 0)
        {
            painter->setPen(hourHandPen);
            painter->drawLine(0, -190, 0, -170);


            painter->setPen(qRgb(220,195,195));
            painter->drawText(-20, -165, 40, 40,
              Qt::AlignHCenter | Qt::AlignTop,QString::number(i/5));
        }
        else
        {
            painter->setPen(minuteHandPen);
            painter->drawLine(0, -190, 0, -175);
        }
        painter->restore();
    }
}


void MainWindow::gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight) {
    QRadialGradient gradient(0, 0, radius);
    gradient.setColorAt(0, qRgb(255,225,255));
    painter->setBrush(gradient);


    QRectF rect(-radius, -radius, radius<<1, radius<<1);
    QPainterPath path;
    path.arcTo(rect, startAngle, angleLength);


    QPainterPath subPath;
    subPath.addEllipse(rect.adjusted(arcHeight, arcHeight, -arcHeight, -arcHeight));
    path -= subPath;


    painter->setPen(Qt::NoPen);
    painter->drawPath(path);
}




void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    QPixmap map("://jpg/Sul 01.jpg");

    QRect q(0,0,1200,1063);

    QRect q2(0,0,width(),height());

    painter.drawPixmap(q2,map,q);

    painter.setRenderHint(QPainter::Antialiasing,true);

    int radius = 10;
    int arcHeight = 5;

    painter.translate(800,200);//将坐标轴移动到合适位置


    gradientArc(&painter, radius, 0, 360, arcHeight);


    painter.setBrush(Qt::black);
    painter.setPen(Qt::white);
    painter.drawConvexPolygon(hourHand,4);//绘制时针


    painter.setBrush(Qt::black);
    painter.setPen(Qt::white);
    painter.drawConvexPolygon(minuteHand,4);//绘制分针


    painter.setBrush(Qt::black);
    painter.setPen(Qt::white);
    painter.drawConvexPolygon(secondHand,4);//绘制秒针


    drawClockDial(&painter);//坐标轴复位


}



效果图
在这里插入图片描述

让时钟动起来(重绘时钟)

代码:

// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPen>
#include <QFont>
#include <QPaintEvent>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE


class MainWindow : public QMainWindow
{
    Q_OBJECT


public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void paintEvent(QPaintEvent * event);

private:
    Ui::MainWindow *ui;


    static const QPoint hourHand[4];
    static const QPoint minuteHand[4];
    static const QPoint secondHand[4];
    QPen hourHandPen;
    QPen minuteHandPen;
    QFont font;


    void gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight);


protected:
    void drawHourHand(QPainter *painter);
    void drawMinuteHand(QPainter *painter);
    void drawsecondHand(QPainter *painter);
    void drawClockDial(QPainter *painter);
};
#endif // MAINWINDOW_H

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QRadialGradient>
#include <QPainterPath>
#include <QTimer>
#include <QTime>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    setWindowTitle("Clock");
    setWindowIcon(QIcon("://jpg/Sul 01.jpg"));
    resize(1200,1063);


    font.setPointSize(16);
    font.setFamily("华文行楷");
    font.setBold(false);
    setFont(font);


    QTimer *timer = new QTimer(this);
    timer->start(1000);//一秒钟
    connect(timer,SIGNAL(timeout()),this,SLOT(update()));//详见时钟实现原理
}


MainWindow::~MainWindow()
{
    delete ui;
}


const QPoint MainWindow::hourHand[4] = {
    QPoint(10, 4),
    QPoint(0, -15),
    QPoint(-10, 4),
    QPoint(0, -65)
        };


const QPoint MainWindow::minuteHand[4] = {
    QPoint(6, 5),
    QPoint(0, -20),
    QPoint(-6, 5),
    QPoint(0, -120)
        };


const QPoint MainWindow::secondHand[4] = {
    QPoint(4, 5),
    QPoint(0, 20),
    QPoint(-4, 5),
    QPoint(0, -180)
        };


void MainWindow::drawHourHand(QPainter *painter)
{
    QTime time = QTime::currentTime();//获取时间
    QRadialGradient gradient(225,210,210);
    gradient.setColorAt(0, qRgb(225,210,210));
    painter->setBrush(gradient);//重绘的指针颜色
    painter->setPen(qRgb(215,180,180));//指针边界颜色
    painter->save();//保存坐标
    painter->rotate(30.0*(time.hour()+time.minute()/60.0));//偏移角度
    painter->drawConvexPolygon(hourHand,4);//绘制时针
    painter->restore();//坐标复位
}


void MainWindow::drawMinuteHand(QPainter *painter)
{
    QTime time = QTime::currentTime();
    QRadialGradient gradient(225,220,220);
    gradient.setColorAt(0, qRgb(225,220,220));
    painter->setBrush(gradient);
    painter->setPen(qRgb(215,180,180));
    painter->save();
    painter->rotate(6.0*(time.minute()+time.second()/60.0));
    painter->drawConvexPolygon(minuteHand,4);
    painter->restore();
}


void MainWindow::drawsecondHand(QPainter *painter)
{
    QTime time = QTime::currentTime();
    QRadialGradient gradient(225,230,230);
    gradient.setColorAt(0, qRgb(225,230,230));
    painter->setBrush(gradient);
    painter->setPen(qRgb(215,180,180));
    painter->save();
    painter->rotate(6.0*time.second());
    painter->drawConvexPolygon(secondHand,4);
    painter->restore();
}




void MainWindow::drawClockDial(QPainter *painter)
{
    QPen pen1;
    pen1.setWidth(4);
    pen1.setColor(qRgb(204,197,193));
    hourHandPen = pen1;

    QPen pen2;
    pen2.setWidth(2);
    pen2.setColor(qRgb(220,195,195));
    minuteHandPen = pen2;

     for (int i = 1; i <=60; ++i)
    {
        painter->save();
        painter->rotate(6*i);
        if (i % 5 == 0)
        {
            painter->setPen(hourHandPen);
            painter->drawLine(0, -190, 0, -170);


            painter->setPen(qRgb(220,195,195));
            painter->drawText(-20, -165, 40, 40,
              Qt::AlignHCenter | Qt::AlignTop,QString::number(i/5));
        }
        else
        {
            painter->setPen(minuteHandPen);
            painter->drawLine(0, -190, 0, -175);
        }
        painter->restore();
    }
}


void MainWindow::gradientArc(QPainter *painter, int radius, int startAngle, int angleLength, int arcHeight) {
    QRadialGradient gradient(0, 0, radius);
    gradient.setColorAt(0, qRgb(255,225,255));
    painter->setBrush(gradient);


    QRectF rect(-radius, -radius, radius<<1, radius<<1);
    QPainterPath path;
    path.arcTo(rect, startAngle, angleLength);


    QPainterPath subPath;
    subPath.addEllipse(rect.adjusted(arcHeight, arcHeight, -arcHeight, -arcHeight));
    path -= subPath;


    painter->setPen(Qt::NoPen);
    painter->drawPath(path);
}




void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    QPixmap map("://jpg/Sul 01.jpg");

    QRect q(0,0,1200,1063);

    QRect q2(0,0,width(),height());

    painter.drawPixmap(q2,map,q);

   painter.setRenderHint(QPainter::Antialiasing,true);

    int radius = 10;
    int arcHeight = 5;

    painter.save();
    painter.translate(800,200);

    gradientArc(&painter, radius, 0, 360, arcHeight);

//    painter.setBrush(Qt::black);
//    painter.setPen(Qt::white);
//    painter.drawConvexPolygon(hourHand,4);//绘制时针


//    painter.setBrush(Qt::black);
//    painter.setPen(Qt::white);
//    painter.drawConvexPolygon(minuteHand,4);//绘制分针


//    painter.setBrush(Qt::black);
//    painter.setPen(Qt::white);
//    painter.drawConvexPolygon(secondHand,4);//绘制秒针

    drawClockDial(&painter);
    drawHourHand(&painter);
    drawMinuteHand(&painter);
    drawsecondHand(&painter);

    painter.restore();
}

效果图:
在这里插入图片描述
至此,时钟制作完毕

参考:

QT开发(十六)——QT绘图实例-钟表

引用:

Piniv Sul かぐや様 id=81060761 (https://www.pixiv.net/artworks/81060761)

  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值