用基础图形做一个钟表
简述
利用Qpainter可以画出一些简单的图形,再将这些简单的图形组合,配合一些其他的函数和事件,就能实现一个基础的钟表。
效果图
代码实现
- 设置背景图片(此步骤可以省略,根据需要添加)
//设置背景图片
QPixmap map(":/rec/1_13.png");
QRect q(0,0,1892,990);
QRect q2(0,0,width(),height());
painter.drawPixmap(q2,map,q);
- 设置窗口名称和图标
setWindowTitle("clock");//窗口名称
setWindowIcon(QIcon((":/rec/zhong.png")));//窗口图标
- 设置定时器,时间间隔为1000毫秒,并且将定时器时间与update函数关联为信号和槽,定时器每隔1秒发送一个信号,update接到信号后自动调用paintEvent事件。
QTimer *timer1 = new QTimer(this);
connect(timer1, SIGNAL(timeout()), this, SLOT(update()));
timer1->start(1000);
4.绘制时针分针秒针的形状
// 时针、分针、秒针 - 多边形
static const QPoint hourHand[3] = {
QPoint(3, 8),
QPoint(-3, 8),
QPoint(0, -40)
};
static const QPoint minuteHand[3] = {
QPoint(3, 8),
QPoint(-3, 8),
QPoint(0, -65)
};
static const QPoint secondHand[3] = {
QPoint(3, 8),
QPoint(-3, 8),
QPoint(0, -80)
};
5.设置颜色(此步骤可以省略,根据需要添加)
QColor hourColor(130,57,53, 200);
QColor minuteColor(0, 127, 127, 150);
QColor secondColor(0, 160, 230, 150);
6.获取系统时间,平移坐标系
QTime time = QTime::currentTime();//获取系统时间
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2);// 平移坐标系原点至中心点
painter.scale(qMin(width(), height())/ 200.0, qMin(width(), height())/ 200.0); // 缩放
painter.drawEllipse(-96,-96,192,192);//画制边框圆
7.绘制时针和时刻度线
// 绘制时针
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
painter.save();
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 3);
painter.restore();
painter.setPen(hourColor);
// 绘制时刻度线
for (int i = 0; i < 12; ++i)
{
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
QFont font = painter.font();
font.setBold(true);
painter.setFont(font);
8.绘制小时文本
预先设置的接口:
QRectF Widget::textRectF(double radius, int pointSize, double angle)
{
QRectF rectF;
rectF.setX(radius*cos(angle*M_PI/180.0) - pointSize*2);
rectF.setY(radius*sin(angle*M_PI/180.0) - pointSize/2.0);
rectF.setWidth(pointSize*4);
rectF.setHeight(pointSize*1.2);
return rectF;
}
// 绘制小时文本
int radius = 100;
int pointSize = font.pointSize();
int nHour = 0;
for (int i = 0; i < 12; ++i)
{
nHour = i + 3;
if (nHour > 12)
nHour -= 12;
painter.drawText(textRectF(radius*0.8, pointSize, i * 30), Qt::AlignCenter, QString::number(nHour));
}
9.绘制分针和分针刻度线
// 绘制分针
painter.setPen(Qt::NoPen);
painter.setBrush(minuteColor);
painter.save();
painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
painter.drawConvexPolygon(minuteHand, 3);
painter.restore();
painter.setPen(minuteColor);
// 绘制分钟刻度线
for (int j = 0; j < 60; ++j)
{
if ((j % 5) != 0)
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
10.绘制秒针
// 绘制秒针
painter.setPen(Qt::NoPen);
painter.setBrush(secondColor);
painter.save();
painter.rotate(6.0 * time.second());
painter.drawConvexPolygon(secondHand, 3);
painter.restore();
源代码
头文件
#ifndef CLOCK_H
#define CLOCK_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
QRectF textRectF(double radius, int pointSize, double angle);
void paintEvent(QPaintEvent *event);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QTime>
#include <QPainter>
#include <QFont>
#include <QPixmap>
#include <QIcon>
#define M_PI 3.1415926535898
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("clock");
setWindowIcon(QIcon((":/rec/zhong.png")));//窗口图标
QTimer *timer1 = new QTimer(this);
connect(timer1, SIGNAL(timeout()), this, SLOT(update()));
timer1->start(1000);
}
Widget::~Widget()
{
delete ui;
}
QRectF Widget::textRectF(double radius, int pointSize, double angle)
{
QRectF rectF;
rectF.setX(radius*cos(angle*M_PI/180.0) - pointSize*2);
rectF.setY(radius*sin(angle*M_PI/180.0) - pointSize/2.0);
rectF.setWidth(pointSize*4);
rectF.setHeight(pointSize*1.2);
return rectF;
}
void Widget::paintEvent(QPaintEvent *event)
{
// 时针、分针、秒针 - 多边形
static const QPoint hourHand[3] = {
QPoint(3, 8),
QPoint(-3, 8),
QPoint(0, -40)
};
static const QPoint minuteHand[3] = {
QPoint(3, 8),
QPoint(-3, 8),
QPoint(0, -65)
};
static const QPoint secondHand[3] = {
QPoint(3, 8),
QPoint(-3, 8),
QPoint(0, -80)
};
QColor hourColor(130,57,53, 200);
QColor minuteColor(0, 127, 127, 150);
QColor secondColor(0, 160, 230, 150);
QTime time = QTime::currentTime();//获取系统时间
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2);// 平移坐标系原点至中心点
painter.scale(qMin(width(), height())/ 200.0, qMin(width(), height())/ 200.0); // 缩放
painter.drawEllipse(-96,-96,192,192);//画制边框圆
// 绘制时针
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
painter.save();
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 3);
painter.restore();
painter.setPen(hourColor);
// 绘制时刻度线
for (int i = 0; i < 12; ++i)
{
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
QFont font = painter.font();
font.setBold(true);
painter.setFont(font);
// 绘制小时文本
int radius = 100;
int pointSize = font.pointSize();
int nHour = 0;
for (int i = 0; i < 12; ++i)
{
nHour = i + 3;
if (nHour > 12)
nHour -= 12;
painter.drawText(textRectF(radius*0.8, pointSize, i * 30), Qt::AlignCenter, QString::number(nHour));
}
// 绘制分针
painter.setPen(Qt::NoPen);
painter.setBrush(minuteColor);
painter.save();
painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
painter.drawConvexPolygon(minuteHand, 3);
painter.restore();
painter.setPen(minuteColor);
// 绘制分钟刻度线
for (int j = 0; j < 60; ++j)
{
if ((j % 5) != 0)
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
// 绘制秒针
painter.setPen(Qt::NoPen);
painter.setBrush(secondColor);
painter.save();
painter.rotate(6.0 * time.second());
painter.drawConvexPolygon(secondHand, 3);
painter.restore();
}