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(); }