一、简述
在窗体上绘制一个2D时钟图形,实时显示当前时间。(可以封装成为一个控件)
渐变色--》绘制色环、中心点
旋转平移--》绘制刻度线、数字
多边形--》指针
例子:https://lanzous.com/b00awbcta 密码:bvh6
二、效果
三、工程结构
四、源文件
Time.pro文件
QT += widgets gui
HEADERS += \
clock.h
SOURCES += \
main.cpp \
clock.cpp
clock.h文件
#ifndef CLOCK_H
#define CLOCK_H
#include
#include
#include
#include
#include
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()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
#include "clock.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Clock w;
w.show();
return a.exec();
}