Qt绘制时钟


提示:以下是本篇文章正文内容,下面案例可供参考

1.MainWindow.h

代码如下(示例):

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include <QRectF>
#include <QTime>
#include <QPainter>
#include <qmath.h>

#define M_PI 3.1415926

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QRectF textRectF(double radius, int pointSize, double angle);
    void paintEvent(QPaintEvent *event);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

2.MainWindow.cpp

代码如下(示例):

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowFlags(Qt::SubWindow | Qt::FramelessWindowHint);
    this->setAttribute(Qt::WA_TranslucentBackground, true);
    setWindowState(Qt::WindowMaximized);
    // 构造定时器,设置超时为 1 秒
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(1000);
}

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

QRectF MainWindow::textRectF(double radius, int pointSize, double angle)
{
    QRectF rectF;
    rectF.setX(radius*qCos(angle*M_PI/180.0) - pointSize*2);
    rectF.setY(radius*qSin(angle*M_PI/180.0) - pointSize/2.0);
    rectF.setWidth(pointSize*4);
    rectF.setHeight(pointSize);
    return rectF;
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    // 时针、分针、秒针位置 - 多边形
    static const QPoint hourHand[3] = {
        QPoint(7, 8),
        QPoint(-7, 8),
        QPoint(0, -30)
    };
    static const QPoint minuteHand[3] = {
        QPoint(7, 8),
        QPoint(-7, 8),
        QPoint(0, -65)
    };

    static const QPoint secondHand[3] = {
        QPoint(7, 8),
        QPoint(-7, 8),
        QPoint(0, -80)
    };

    // 时针、分针、秒针颜色
    QColor hourColor(200, 100, 0, 200);
    QColor minuteColor(0, 127, 127, 150);
    QColor secondColor(0, 160, 230, 150);

    int side = qMin(width(), height());
    QTime time = QTime::currentTime();

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    // 平移坐标系原点至中心点
    painter.translate(width() / 2, height() /2);
    // 缩放
    painter.scale(side / 250, side / 250);

    // 绘制时针
    painter.setPen(Qt::NoPen);
    painter.setBrush(hourColor);

    painter.save();
    // 每圈360° = 12h 即:旋转角度 = 小时数 * 30°
    painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
    painter.drawConvexPolygon(hourHand, 3);
    painter.restore();

    painter.setPen(hourColor);

    // 绘制小时线 (360度 / 12 = 30度)
    for (int i = 0; i < 12; ++i) {
        painter.drawLine(88, 0, 96, 0);
        painter.rotate(30.0);
    }

    int radius = 100;
    QFont font = painter.font();
    font.setBold(true);
    painter.setFont(font);
    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();
    // 每圈360° = 60m 即:旋转角度 = 分钟数 * 6°
    painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
    painter.drawConvexPolygon(minuteHand, 3);
    painter.restore();

    painter.setPen(minuteColor);

    // 绘制分钟线 (360度 / 60 = 6度)
    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();
    // 每圈360° = 60s 即:旋转角度 = 秒数 * 6°
    painter.rotate(6.0 * time.second());
    painter.drawConvexPolygon(secondHand, 3);
    painter.restore();
}


效果展示

请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,你可以通过以下步骤实现: 1. 创建一个 QTimer 对象,用于定时器更新。 2. 在定时器的 timeout() 槽函数中,获取当前鼠标的位置并计算出指针所需要旋转的角度。 3. 调用 QWidget 的 update() 函数触发窗口重绘。 4. 在 QWidget 的 paintEvent() 函数中,绘制时钟的表盘和指针,并将指针旋转到之前计算的角度。 下面是一个简单的示例代码: ```c++ #include <QtWidgets> class ClockWidget : public QWidget { public: ClockWidget(QWidget* parent = nullptr) : QWidget(parent) { // 创建 QTimer 对象,每 100 毫秒触发一次 timeout() 槽函数 QTimer* timer = new QTimer(this); timer->setInterval(100); connect(timer, &QTimer::timeout, this, &ClockWidget::update); timer->start(); } protected: void paintEvent(QPaintEvent*) override { // 获取当前时间和鼠标位置 QDateTime now = QDateTime::currentDateTime(); QPoint mousePos = mapFromGlobal(QCursor::pos()); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 绘制表盘 painter.setPen(Qt::NoPen); painter.setBrush(Qt::white); painter.drawEllipse(rect().center(), 100, 100); // 绘制指针 painter.setPen(Qt::black); painter.drawLine(rect().center(), mousePos); painter.save(); painter.translate(rect().center()); painter.rotate(-90 + now.time().hour() * 30 + now.time().minute() * 0.5); painter.drawLine(0, 0, 50, 0); painter.restore(); painter.save(); painter.translate(rect().center()); painter.rotate(-90 + now.time().minute() * 6); painter.drawLine(0, 0, 70, 0); painter.restore(); painter.save(); painter.translate(rect().center()); painter.rotate(-90 + now.time().second() * 6); painter.setPen(Qt::red); painter.drawLine(0, 0, 70, 0); painter.restore(); } }; int main(int argc, char* argv[]) { QApplication app(argc, argv); ClockWidget clock; clock.resize(200, 200); clock.show(); return app.exec(); } ``` 在这个示例中,我们使用 QTimer 对象每 100 毫秒触发一次 timeout() 槽函数。在 timeout() 槽函数中,我们获取当前时间和鼠标位置,计算出指针所需要旋转的角度。然后我们调用 QWidget 的 update() 函数触发窗口重绘。在 paintEvent() 函数中,我们绘制时钟的表盘和指针,并将指针旋转到之前计算的角度。其中,小时指针每小时旋转 30 度,每分钟旋转 0.5 度;分钟指针每分钟旋转 6 度;秒针每秒钟旋转 6 度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值