QT 自定义控件--时钟控件的初步实现

QT 自定义控件--时钟控件

一、简述

    在窗体上绘制一个2D时钟图形,实时显示当前时间。(可以封装称为一个控件)

    渐变色--》绘制色环、中心点

    旋转平移--》绘制刻度线、数字

    多边形--》指针

二、效果


三、工程结构


四、源文件

    Time.pro文件

QT += widgets gui

HEADERS += \
    clock.h

SOURCES += \
    main.cpp \
    clock.cpp

    clock.h文件

#ifndef CLOCK_H
#define CLOCK_H

#include <QDialog>
#include <QPaintEvent>
#include <QPainter>
#include <QTime>
#include <QTimer>
class Clock : public QDialog
{
    Q_OBJECT

public:
    Clock(QWidget *parent = 0);
    ~Clock();
private:
    static const QPoint hourHand[4];//小时指针
    static const QPoint minuteHand[4];//分钟指针
    static const QPoint secondHand[4];//秒指针

protected:
    void paintEvent(QPaintEvent *);//窗体重绘事件
    void drawHourHand(QPainter *painter);//画 时针
    void drawMinuteHand(QPainter *painter);//画 分针
    void drawsecondHand(QPainter *painter);//画 秒针
    void drawClockDial(QPainter *painter);//画 刻度线、数字
    void drawBackgroud(QPainter *painter);//画 背景
    void drawCentre(QPainter *painter);//画 中心点
};
#endif // CLOCK_H

    clock.cpp文件

#include "Clock.h"
const QPoint Clock::hourHand[4] = {               //四边形时针图形的四个角的坐标点
    QPoint(7, 5),//中心点、右侧
    QPoint(0, 20),//针头
    QPoint(-7, 5),//中心点、左侧
    QPoint(0, -40)//针尾    (注意映射后坐标原点是(110,110))
};
const QPoint Clock::minuteHand[4] = {
    QPoint(5, 5),
    QPoint(0, 19),
    QPoint(-5, 5),
    QPoint(0, -70)
};
const QPoint Clock::secondHand[4] = {
    QPoint(3, 5),//右侧
    QPoint(0, 18),//针头
    QPoint(-3, 5),//左侧
    QPoint(0, -90)//针尾
};
Clock::Clock(QWidget *parent)
    : QDialog(parent)
{
    //字体大小设置为10
     QFont font;
     font.setPointSize(10);
    //设置当前字体
    this->setFont(font);
    //创建一个定时器
    QTimer *timer = new QTimer(this);
    //开启定时器,设置为1秒
    timer->start(1000);
    //定时器溢出时,执行相应动作,这里是每一秒进行更新窗体,进行窗体重绘
    connect(timer,SIGNAL(timeout()),this,SLOT(update()));
    //设置窗体标题
    setWindowTitle("时钟");
    //去掉帮助按钮,只留下关闭按钮
    setWindowFlags(Qt::WindowCloseButtonHint);
    //重新设置窗体大小
    resize(420, 420);
}
Clock::~Clock()
{}

void Clock::paintEvent(QPaintEvent *)
{
    //将当前窗体作为画布
    QPainter painter(this);
    //消除锯齿,看起来更加圆滑
    painter.setRenderHint(QPainter::Antialiasing, true);
    // 将绘画原点设置为为窗体中心
    painter.translate(width() / 2, height() / 2);
    //获取 窗体的宽、窗体的高 两个值的较小值
    int size =  width()<height()?width():height();
    //按照比例进行缩放
    painter.scale(size / 220.0, size / 220.0);
    //画背景
    drawBackgroud(&painter);
    //画刻度线、数字
    drawClockDial(&painter);
    //画时针
    drawHourHand(&painter);
    //画分针
    drawMinuteHand(&painter);
    //画秒针
    drawsecondHand(&painter);
    //设置画刷
    painter.setBrush(Qt::black);
    //画中心点
    drawCentre(&painter);
}
void Clock::drawHourHand(QPainter *painter)
{
    //获取当前时间
    QTime time = QTime::currentTime();
    //设置画刷
    painter->setBrush(Qt::black);
    //设置画笔
    painter->setPen(Qt::black);
    //保存当前painter状态到栈中、因为后面旋转后要恢复
    painter->save();
    //旋转角度  1个小时30°(5个刻度)     当前分钟的小时数   当前秒的小时数
    painter->rotate(30.0*(time.hour()+time.minute()/60.0)+time.second()/3600.0);
    //绘制时针  (绘制多边形多边形)
    painter->drawConvexPolygon(hourHand,4);
    //绘制图形后恢复之前painter状态(出栈)
    painter->restore();
}
void Clock::drawMinuteHand(QPainter *painter)
{
    //获取当前时间
    QTime time = QTime::currentTime();
    //设置画刷
    painter->setBrush(Qt::blue);
    //设置画笔
    painter->setPen(Qt::blue);
    //保存当前painter状态到栈中、因为后面旋转后要恢复
    painter->save();
    //旋转角度     1分钟1刻度(6°)         当前秒数的小时数
    painter->rotate(6.0*(time.minute()+time.second()/60.0));
    //绘制分针
    painter->drawConvexPolygon(minuteHand,4);
    //绘制图形后恢复之前状态(出栈)
    painter->restore();
}
void Clock::drawsecondHand(QPainter *painter)
{
    //获取当前时间
    QTime time = QTime::currentTime();
    //设置画刷
    painter->setBrush(Qt::green);
    //设置画笔
    painter->setPen(Qt::green);
    //保存当前painter状态到栈中、因为后面旋转后要恢复
    painter->save();
    //旋转
    painter->rotate(6.0*time.second());
    //绘制秒针
    painter->drawConvexPolygon(secondHand,4);
    //绘制图形后恢复之前painter状态(出栈)
    painter->restore();
}
void Clock::drawClockDial(QPainter *painter)
{
    //绘制钟表刻度盘和数字
    for (int i = 1; i <=60; ++i)
    {
        //保存当前painter状态到栈中、因为后面旋转后要恢复
        painter->save();
        //坐标轴旋转6度  一圈360度,一共12个刻度线,每个刻度线6度
        painter->rotate(6*i);
        if (i % 5 == 0)
        {
            //设置画笔,设置小时刻度线为  前景色            字体大小
            painter->setPen(QPen(palette().foreground(), 2.0));
            //画刻度线
            painter->drawLine(0, -98, 0, -82);
            ///调整角度,让数字正着显示
            // 将绘画原点暂时设置为(0,72)
            painter->translate(0,-72);
            //旋转
            painter->rotate(-6*i);
            //平移
            painter->translate(-4,-6);
            //画数字1~12   文本居中
            painter->drawText(0, 0, 11, 11,Qt::AlignHCenter,QString::number(i/5));
        }
        else
        {
            //设置画笔                    前景色            字体大小
            painter->setPen(QPen(palette().foreground(), 1.0));
            //画线
            painter->drawLine(0, -98, 0, -88);
        }
        // 将绘画原点设置为为窗体中心
        painter->translate(width() / 2, height() / 2);
        //绘制图形后恢复之前painter状态(出栈)
        painter->restore();
    }
}

void Clock::drawBackgroud(QPainter *painter)
{
    //消除锯齿,看起来更加圆滑
    painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);;
    //辐射渐变(从圆的边渐变到焦点)                    圆心         半径        焦点
    QRadialGradient radialGradient(QPointF(0, 0),110,QPointF(0,0));
    //从圆的边渐变到焦点,刻度从1~0,下面例子:在1~0.9刻度从颜色1渐变到颜色2,在0.9~0.89刻度从颜色2渐变到颜色3
    radialGradient.setColorAt(1, QColor(65, 205, 82, 200));//颜色1
    radialGradient.setColorAt(0.9, QColor(64, 200, 80, 100));//颜色2
    radialGradient.setColorAt(0.89, QColor(0, 0, 0, 200));//颜色3
    //边框线无色
    painter->setPen(Qt::NoPen);
    //使用辐射渐变作为画刷
    painter->setBrush(radialGradient);
    //画一个圆                椭圆中心       短轴 长轴
    painter->drawEllipse(QPointF(0, 0), 110, 110);
}

void Clock::drawCentre(QPainter *painter)
{
    //画中心点
    //角度渐变
    QConicalGradient coneGradient(0, 0, -90.0);
    //渐变颜色、渐变位置设置
    coneGradient.setColorAt(0.0, Qt::darkGray);
    coneGradient.setColorAt(0.2, QColor(150, 150, 200));
    coneGradient.setColorAt(0.5, Qt::white);
    coneGradient.setColorAt(1.0, Qt::darkGray);
    //没有线,填满没有边界
    painter->setPen(Qt::NoPen);
    //设置画刷
    painter->setBrush(coneGradient);
    //绘制椭圆
    painter->drawEllipse(-5, -5, 10, 10);
}

    main.cpp文件

#include <QApplication>
#include "clock.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Clock w;
    w.show();
    return a.exec();
}


猜你喜欢

转载自blog.csdn.net/nanfeibuyi/article/details/80396751