Qt 绘制炫彩时钟

录制_2022_09_15_09_44_58_720

思路:

 1.  使用定时器,每秒给 “秒值” 增加 1, 当 “秒值” 等于 60 时, 给“分值”增加1, 当分值为60时,给“时值” 加1

2. 绘制界面时, 可以用信号槽触发, 也可以调用函数触发,我这里用的是函数调用。

3. 传递的时间,需要转换为角度,用于旋转 时钟指针

4. 每次绘制时候, 需要先对 painter 进行保存, 结束后进行恢复

5. 本例 采用 “视口”和 “窗口” 进行绘制, 这样方便绘制时各个参数设置

界面布局

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QIntValidator>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->setWindowTitle(tr("炫彩时钟"));

    QTime currectTime = QTime::currentTime();
    ui->spinBox_hour->setValue(currectTime.hour());
    ui->spinBox_minutes->setValue(currectTime.minute());
    ui->spinBox_seconds->setValue(currectTime.second());

    QTimer *timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,&MainWindow::on_timeout);
    timer->start(1000);   // 一秒一次
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_timeout()
{
   ui->spinBox_seconds->setValue(ui->spinBox_seconds->value()+1);
}

void MainWindow::on_spinBox_seconds_valueChanged(int arg1)
{
    if(arg1 == 60)
    {
        ui->spinBox_seconds->setValue(0);
        int minus = ui->spinBox_minutes->value() + 1;
        ui->spinBox_minutes->setValue(minus);
    }

    ui->widget->runing(ui->spinBox_hour->value(),ui->spinBox_minutes->value(),ui->spinBox_seconds->value());
}

void MainWindow::on_spinBox_minutes_valueChanged(int arg1)
{
    if(arg1 == 60)
    {
        ui->spinBox_minutes->setValue(0);
        int hour =  ui->spinBox_hour->value() + 1;
        ui->spinBox_hour->setValue(hour);
    }

     ui->widget->runing(ui->spinBox_hour->value(),ui->spinBox_minutes->value(),ui->spinBox_seconds->value());
}

void MainWindow::on_spinBox_hour_valueChanged(int arg1)
{
    if(arg1 == 24)
    {
        ui->spinBox_hour->setValue(0);
        int day = ui->spinBox_day->value() + 1;
        ui->spinBox_day->setValue(day);
    }

     ui->widget->runing(ui->spinBox_hour->value(),ui->spinBox_minutes->value(),ui->spinBox_seconds->value());
}
ClockQWidget.h  
#ifndef CLOCKQWIDGET_H
#define CLOCKQWIDGET_H

#include <QWidget>
#include <QPainter>
#include <QFont>
#include <QPixmap>
#include <QFontMetrics>
#include <QtMath>
#include <QRandomGenerator>

class ClockQWidget : public QWidget
{
    Q_OBJECT
public:
    explicit ClockQWidget(QWidget *parent = nullptr);

    void runing(int hour, int minute, int second);

protected:
    void paintEvent(QPaintEvent *) override;

signals:

private:
    QPoint CustomRotate(QPointF point,qreal from_angle,qreal rotate);

    void drawCalibration(QPainter &painter);

    void drawingNumbers(QPainter &painter);

    void drawTheSecondHand(QPainter &painter);

    void drawTheHourHand(QPainter &painter);

    void drawTheMiunteHand(QPainter &painter);

    QColor randomColor();



 private:
    qreal secondAngle;
    qreal minuteAngle;
    qreal hourAngle;

};

#endif // CLOCKQWIDGET_H

ClockQWidget.cpp

 

#include "clockqwidget.h"

ClockQWidget::ClockQWidget(QWidget *parent) : QWidget(parent)
{

}

void ClockQWidget::runing(int hour, int minute, int second)
{
    int m_hour = hour;
    if ( m_hour >= 12)
        m_hour -= 12;

     hourAngle = (m_hour * 60 * 60 + minute* 60 + second) * 360.0/(12*60*60);   // 时针角度

     minuteAngle = (minute * 60 + second) * 360.0/(60*60);    // 分针角度

     secondAngle = second * 360.0 / 60;     // 秒针角度

     update();
}

void ClockQWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::TextAntialiasing);

    painter.setWindow(-200,-200,400,400);   // 绘制区域
    int viewWidth = qMin(this->height(),this->width());
    painter.setViewport( qRound((this->width() -viewWidth) * 0.5),qRound((this->height() -viewWidth) * 0.5), viewWidth,viewWidth);  // 显示区域

    painter.translate(0,0);

    // 绘制外环圈
    painter.save();
    painter.setPen(QPen(randomColor(),8));
    painter.setBrush(Qt::white);
    painter.drawEllipse(-190,-190,380,380);
    painter.restore();

    // 绘制刻度
    drawCalibration(painter);

    // 绘制数字
    drawingNumbers(painter);

    // 绘制时针
    drawTheHourHand(painter);

    // 绘制分针
    drawTheMiunteHand(painter);

    // 绘制秒针
    drawTheSecondHand(painter);

    // 绘制中心圆点
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::red);
    painter.drawEllipse(-10,-10,20,20);
}

void ClockQWidget::drawCalibration(QPainter &painter)
{
    QColor color1 = randomColor();
    QColor color2 = randomColor();

    for(int i=0;i<60;i++)
    {
        painter.save();

        painter.rotate(i*6);

        if (i % 5 == 0)
        {
            painter.setPen(QPen(color1,3));
            painter.drawLine(QPointF(0,-180), QPointF(0,-165));
        }
        else
        {
//            painter.setPen(QPen(color2));
            painter.drawLine(QPointF(0,-180), QPointF(0,-172));
        }

        painter.restore();
    }
}

QPoint ClockQWidget::CustomRotate(QPointF point, qreal from_angle, qreal rotate)
{
    const qreal PI=3.141592653589;
    QPointF Tmp;
    int newAngle = rotate+from_angle + 90;
    if ( newAngle > 360)
        newAngle -= 360;

    qreal arc = newAngle/180.0*PI;
    qreal Length = qSqrt(point.x()*point.x() +point.y()*point.y());
    Tmp.setX(Length*qCos(arc));
    Tmp.setY(-Length*qSin(arc));
    return Tmp.toPoint();
}

void ClockQWidget::drawingNumbers(QPainter &painter)
{
    painter.save();

    painter.setFont(QFont(0,24,0));
    QPoint point(0,-143);        //从(100,0)开始填文字
    int angle = 0;
    QFontMetrics *fontMet = new QFontMetrics(painter.font());
    for(int i = 12 ; i > 0; i--)
    {
       painter.setPen(randomColor());
       QRect rec = fontMet->boundingRect(QString("%1").arg(i));
       painter.drawText(point.x()-rec.width() * 0.5, point.y() - rec.height() * 0.5 ,rec.width(),rec.height(),Qt::AlignCenter,QString("%1").arg(i));
       point = CustomRotate(point,angle, 30);         //以当前angle度,逆时针旋转30度
       angle += 30;           //更新度数,由于逆时针,所以用加
    }

    painter.restore();
}

void ClockQWidget::drawTheHourHand(QPainter &painter)
{
    painter.save();

    QPixmap disc(":/Images/Image/hour.png");

    /* 旋转的角度 */
    painter.rotate(hourAngle);

    painter.drawPixmap(-15,-90,30,100, disc);

    painter.restore();
}

void ClockQWidget::drawTheMiunteHand(QPainter &painter)
{
    painter.save();

    QPixmap disc(":/Images/Image/minute.png");


    /* 旋转的角度 */
    painter.rotate(minuteAngle);

    painter.drawPixmap(-8,-110,16,120, disc);

    painter.restore();
}

QColor ClockQWidget::randomColor()
{
      QColor color(
                    QRandomGenerator::global()->bounded(0,256),
                    QRandomGenerator::global()->bounded(0,256),
                    QRandomGenerator::global()->bounded(0,256)
                  );
    return color;
}

void ClockQWidget::drawTheSecondHand(QPainter &painter)
{
    painter.save();

    QPixmap disc(":/Images/Image/second.png");

    /* 旋转的角度 */
    painter.rotate(secondAngle);

    /* 画图操作 */
    painter.drawPixmap(-5,-120,10,120, disc);

    painter.restore();
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值