源码:
lclock.h
#ifndef LCLOCK_H
#define LCLOCK_H
#include <QWidget>
#include <QTime>
class LClock : public QWidget
{
Q_OBJECT
public:
explicit LClock(QWidget *parent = nullptr);
protected:
void paintEvent(QPaintEvent* event) override;
signals:
public slots:
private:
int nSide;
QRect viewPortRect;
int nRaduis;
int nWindowSize = 200;
QRect backRect;
QColor hourColor = QColor(127,0,127);
QColor minuteColor = QColor(0,127,127,191);
QColor secondColor = QColor(255,0,0,191);
QPoint hourHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -40)
};
QPoint minuteHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -70)
};
QPoint secondHand[3] = {
QPoint(3, 8),
QPoint(-3, 8),
QPoint(0, -70)
};
double m_pi = 3.1415926;
void drawBackRect(QPainter* painter);// 画背景视窗
void drawDial(QPainter* painter);// 画圆形表盘
void drawScaleNum(QPainter* painter);// 画刻度值
void drawHour(QPainter* painter,QTime& time);// 画时针
void drawMinute(QPainter* painter,QTime& time);// 画分针
void drawSecond(QPainter* painter,QTime& time);// 画秒针
void drawWeek(QPainter* painter,QTime& time);// 画星期和上下午
};
#endif // LCLOCK_H
lclock.cpp
#include "lclock.h"
#include <QStyleOption>
#include <QPainter>
#include <QTimer>
#include <QDateTime>
LClock::LClock(QWidget *parent) : QWidget(parent)
{
QTimer *timer = new QTimer(this);
connect(timer,&QTimer::timeout,this,QOverload<>::of(&LClock::update));
timer->start(1000);
}
void LClock::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QTime time = QTime::currentTime();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 获取画图区域
nSide = qMin(width(),height())-2;
// 设置视窗
QPoint ptCenter = QPoint(width()/2,height()/2);
viewPortRect = QRect(ptCenter.x() - nSide/2,ptCenter.y() - nSide/2,nSide,nSide);
painter.setViewport(viewPortRect);
backRect = QRect(-nWindowSize/2,-nWindowSize/2,nWindowSize,nWindowSize);
painter.setWindow(backRect);
// 画矩形区域
//drawBackRect(&painter);
// 画圆形
drawDial(&painter);
// 画星期,上下午
drawWeek(&painter,time);
// 画刻度线
drawScaleNum(&painter);
// 画时针
drawHour(&painter,time);
drawMinute(&painter,time);
drawSecond(&painter,time);
}
// 画背景视窗
void LClock::drawBackRect(QPainter* painter)
{
painter->save();
QPen pen(QBrush(Qt::black),1,Qt::PenStyle::DotLine);
painter->setPen(pen);
painter->drawRect(backRect);
painter->fillRect(backRect,Qt::transparent);
painter->restore();
}
// 画圆形表盘
void LClock::drawDial(QPainter* painter)
{
painter->save();
QPen pen = painter->pen();
pen.setWidth(1);
pen.setStyle(Qt::PenStyle::SolidLine);
painter->setPen(pen);
//QRect rect = QRect(backRect.x()+2,backRect.y()+2,backRect.width()-4,backRect.height() -4);
painter->drawEllipse(backRect);
painter->restore();
painter->save();
}
// 画刻度线和刻度值
void LClock::drawScaleNum(QPainter* painter)
{
painter->save();
// 一共需要画60条刻度线,5的倍数处,画长线,其它画短线
for (int i =1;i<=60;i++) {
painter->rotate(6);
if (i%5 == 0) {// 长线
painter->setPen(hourColor);
painter->drawLine(92,0,100,0);
} else {// 短线
painter->setPen(minuteColor);
painter->drawLine(96,0,100,0);
}
}
painter->restore();
// 画刻度值
painter->setPen(QPen(QColor(0,0,0)));
int numRadius = 80;
for (int i = 1;i<=12;i++) {
int offsetAngle = i*30;
QString strValue = QString::number(i);
double textWidth = fontMetrics().width(strValue);
double textHeight = fontMetrics().height();
QPointF pt(numRadius*sin((offsetAngle/360.0)*2.0*m_pi),-numRadius*cos((offsetAngle/360.0)*2.0*m_pi));
pt.setX(pt.x()-textWidth/2);
pt.setY(pt.y() + textHeight/4);
painter->drawText(pt,QString::number(i));
}
}
// 画时针
void LClock::drawHour(QPainter* painter,QTime& time)
{
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(hourColor);
int offsetAngle = 30.0*(time.hour()+time.minute()/60.0);
painter->rotate(offsetAngle);
painter->drawConvexPolygon(hourHand,3);
painter->restore();
}
// 画分针
void LClock::drawMinute(QPainter* painter,QTime& time)
{
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(minuteColor);
int offsetAngle = time.minute()*6;
painter->rotate(offsetAngle);
painter->drawConvexPolygon(minuteHand,3);
painter->restore();
}
// 画秒针
void LClock::drawSecond(QPainter* painter,QTime& time)
{
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(secondColor);
int offsetAngle = time.second()*6;
painter->rotate(offsetAngle);
painter->drawConvexPolygon(secondHand,3);
painter->restore();
}
// 画星期
void LClock::drawWeek(QPainter* painter,QTime& time)
{
painter->save();
QString strWeek=QDateTime::currentDateTime().toString(QString::fromLocal8Bit("MM月dd日 ddd"));
if (time.hour() >= 12) {
strWeek += QStringLiteral( "下午");
} else {
strWeek += QStringLiteral("上午");
}
double textWidth = fontMetrics().width(strWeek);
double textHeight = fontMetrics().height();
QRect rect(-textWidth/2 -2,50,textWidth+4,textHeight);
painter->fillRect(rect,Qt::darkGray);
painter->setPen(Qt::white);
painter->drawText(rect,strWeek);
painter->restore();
}
使用:
void MainWindow::initUI()
{
lClock = new LClock(ui->centralWidget);
lClock->setObjectName(QString::fromUtf8("lClock"));// 这个名称会保存,应该有一个string和指针的map结构
horizontalLayout = new QHBoxLayout(ui->centralWidget);
horizontalLayout->setSpacing(6);
horizontalLayout->setContentsMargins(11,11,11,11);
horizontalLayout->setObjectName("horizontalLayout");
horizontalLayout->addWidget(lClock);
}