Qt绘图实例——绘制时钟(钟表+表框)

一.效果展示

在这里插入图片描述

二.基本思路

首先是将表盘和时、分、秒针以及表框“绘制”出来,然后设置定时器,定时器每隔一秒发送timeout()信号到QWidget::update()槽函数,update()槽函数将会重绘一次窗口,重写重绘事件函数paintEvent(QPaintEvent *event),根据获取的当前系统时间的时钟、分钟、秒钟重绘钟表的时针、分针、秒针。

三.各部分绘制思路+实现代码

1.“绘制”时针、分针、秒针

定义三个数组,数组中的四个点连起来就是时针、分针、秒针。

const QPoint Widget::hourHand[4] = {
    QPoint(3, 5),
    QPoint(0, 13),
    QPoint(-3, 5),
    QPoint(0, -40)
};
const QPoint Widget::minuteHand[4] = {
    QPoint(3, 5),
    QPoint(0, 16),
    QPoint(-3, 5),
    QPoint(0, -70)
};
const QPoint Widget::secondHand[4] = {
    QPoint(3, 5),
    QPoint(0, 18),
    QPoint(-3, 5),
    QPoint(0, -90)
};

2.绘制表盘

在绘制刻度和数字的时候选择利用循坏同时进行。开始的save()函数是保存调整前的局部界面,最后的restore()函数是恢复到save()保存的那个界面,这两个函数在代码中的作用是保持坐标轴的一致性。之后每旋转6度就绘制一条刻度线,然后if (i % 5 == 0)即在整时的时候加上数字并将刻度线拉长加粗。
具体代码如下:

void Widget::drawClockDial(QPainter *painter)
{
    //绘制钟表刻度盘和数字
    for (int i = 1; i <=60; ++i)
    {
        painter->save();
        painter->rotate(6*i);//坐标轴旋转6度
        if (i % 5 == 0)
        {
            painter->setPen(hourHandPen);
            painter->drawLine(0, -98, 0, -82);
            painter->drawText(-20, -82, 40, 40,
                              Qt::AlignHCenter | Qt::AlignTop,
                              QString::number(i/5));
        }
        else
        {
            painter->setPen(minuteHandPen);
            painter->drawLine(0, -98, 0, -88);
        }
        painter->restore();//绘制图形后复位坐标系
    }
}

3.设制背景——绘制表框

在事件函数中写入上次写到的填入背景图,这个背景图就是一个表框,然后让其铺满整个对话框,实现表框的绘制。

    QPainter painter(this);
    QPixmap map(":/res/1234.jpg");
    QRect q(0,0,220,220);
    QRect q2(0,0,width(),height());
    painter.drawPixmap(q2,map,q);

绘制表框需要在源文件中添加类库

#include"QPixmap"

4.其他设置

    hourHandPen = QPen(palette().foreground(), 2.0);//调色板,2.0,1.0为颜色代码,这里是调整刻度线的颜色
    minuteHandPen = QPen(palette().foreground(), 1.0);
    font.setPointSize(10);//字体大小设定为10
    setFont(font);//设定默认字体
    setWindowTitle("The Clock");//设置对话框名称
    resize(220, 220);//重设对话框大小

四.各部分基本原理+实现代码(表盘+时、分、秒针+表框)

1.计时器

设定槽函数,每一秒钟调用一次事件函数

    QTimer *timer = new QTimer(this);
    timer->start(1000);//一秒钟
    connect(timer,SIGNAL(timeout()),this,SLOT(update()));

2.重绘时针函数

根据获取的时间的小时数(分钟数也化为小时数)乘上30°将时针进行旋转,从而实现时针的实时走动。

void Widget::drawHourHand(QPainter *painter)
{
    QTime time = QTime::currentTime();//获取当前系统的时间
    painter->setBrush(Qt::black);//设定黑色画笔
    painter->setPen(Qt::black);//将时针调成黑色
    painter->save();
    painter->rotate(30.0*(time.hour()+time.minute()/60.0));
    painter->drawConvexPolygon(hourHand,4);//绘制时针
    painter->restore();//绘制图形后复位坐标系
}

3.重绘分针函数

分针函数与时针函数基本相同,只是将实时的分钟数乘上6°旋转分钟(实际上是旋转坐标轴,然后在绘制的时候就看起来是分针在走动)。

void Widget::drawMinuteHand(QPainter *painter)
{
    QTime time = QTime::currentTime();
    painter->setBrush(Qt::blue);
    painter->setPen(Qt::blue);
    painter->save();
    painter->rotate(6.0*(time.minute()+time.second()/60.0));
    painter->drawConvexPolygon(minuteHand,4);//绘制分针
    painter->restore();//绘制图形后复位坐标系
}

4.重绘秒针函数

实现原理与上面一致,秒针旋转的度数就直接是秒钟数乘上6°。

void Widget::drawsecondHand(QPainter *painter)
{
    QTime time = QTime::currentTime();
    painter->setBrush(Qt::red);
    painter->setPen(Qt::red);
    painter->save();//保存坐标系,防止坐标系跑偏了
    painter->rotate(6.0*time.second());//注意是6.0,不是6
    painter->drawConvexPolygon(secondHand,4);//绘制秒针
    painter->restore();//绘制图形后复位坐标系
}

5.事件函数

事件函数为Qt中的主要函数,是在运行时被自动调用的函数,然后计时器每一秒钟调用一次事件函数,同时事件函数调用重绘函数,实现钟表的重现绘制,从而实现时针、分针、秒针的走动。

    painter.setRenderHint(QPainter::Antialiasing, true);
    int side = qMin(width(), height());
    painter.setViewport((width() - side) / 2, (height() - side) / 2,
                        side, side);//让时钟的位置处于对话框的中心
    painter.setWindow(0, 0, 200, 200);
    painter.translate(100,100);//重新设定坐标原点
    //调用重绘函数
    drawClockDial(&painter);
    drawHourHand(&painter);
    drawMinuteHand(&painter);
    drawsecondHand(&painter);
     //绘制黑色外圆圈将刻度和数字包围起来
    painter.setBrush(Qt::black);
    painter.drawEllipse(QPoint(0,0),3,3);

五.补充部分

在头文件中添加使用到的类库

#include <QPaintEvent>
#include <QPainter>
#include <QTime>
#include <QTimer>
#include <QPen>
#include <QFont>

声明Widget的成员函数及变量
(一般变量写在private中,函数protected中,有利于继承过程中封装性的维护)

private:
    static const QPoint hourHand[4];
    static const QPoint minuteHand[4];
    static const QPoint secondHand[4];
    QPen hourHandPen;
    QPen minuteHandPen;
    QFont font;
    Ui::Widget *ui;
protected:
    void paintEvent(QPaintEvent *event);
    void drawHourHand(QPainter *painter);
    void drawMinuteHand(QPainter *painter);
    void drawsecondHand(QPainter *painter);
    void drawClockDial(QPainter *painter);

感谢大家的浏览,如有错误,请不吝赐教!

  • 13
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值