Qt 画一个时钟

100 篇文章 20 订阅

 

源码:

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值