Qt 绘制炫彩时钟

2023-11-12

录制_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();
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt 绘制炫彩时钟 的相关文章

  • 获取小部件的背景颜色 - 真的

    我无法获取小部件的实际背景颜色 在我的特殊情况下 我在使用 QTabWidget 中的小部件时遇到问题 这是在Windows7上 因此 经典的小部件有一些灰色背景 而选项卡内的小部件通常用白色背景绘制 I tried def bgcolor
  • [本机]:在Qt for Android中使用Java函数和第3方库[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 最近我用qt写了一个android应用程序 但我有一个很大的问题 我可以使用 调用一些原生的android API 比如调用特殊的activit
  • 安装多个版本的 Qt 库

    我在windows中安装了QtSDK 它的Qt库版本是4 7 0 现在我想为 mingw 和 VS2008 安装 Qt 库版本 4 8 2 我怎样才能做到这一点 如何向QtCreator引入多个版本 注意 我已经从以下位置下载了库http
  • Qt 支持在 QIcon 中为 SVG 着色

    看来 Qt 不支持 SVG 中路径标签上的描边 填充选项
  • 仅将非模态 QDialog 窗口放置在我的应用程序顶部,而不是所有应用程序顶部

    我有一个 QDialog 窗口 它应该始终位于我的应用程序顶部 它不是模态的 用户可以随时与对话框和主应用程序进行交互 使用窗口保持在顶部提示在某种程度上实现了这一点 但是 该对话框仍然位于所有其他正在运行的应用程序 例如记事本 chrom
  • QGraphicsView 和 eventFilter

    这个问题已经困扰我两天多了 所以我想我应该问一下 我在Win7上使用Qt 4 5 3 用VC2008编译 我有 MyGraphicsView 继承 QGraphicsView 和 MyFilter 继承 QObject 类 当我将 MyFi
  • 如何在 Qt-Embedded 中(正确)输出多语言文本?

    我的目标系统是 linux 3 3 7 Qt Embedded 开源版 4 8 Droid 字体 取自 fonts droid 20111207 git 1 all deb Debian 软件包并复制到 usr lib fonts目录 主要
  • Qt程序部署到多平台,如何?

    我是 Qt 编程新手 我想开发一个程序 我想在 Windows Linux ubuntu 和 Mac 上运行 听说Qt支持多平台应用程序开发 但我的问题是 在我部署或编译后 任何 Qt 库都需要在 Ubuntu 中运行这个应用程序吗 如果您
  • 程序意外完成 - QT Creator

    我正在尝试使用 QT Creator 使用 QT 框架开发 GUI 控制台应用程序 我使用的是Windows XP 我安装了QT 4 8 3和mingw 两者均已安装 没有任何错误 然后我安装了QT Creator QT 版本 路径中的 Q
  • 当我尝试构建 Qt 4.7.1 静态库时,“找不到 -ljscore”

    我尝试从最新的源构建静态 Qt 库 但出现以下错误 usr bin ld cannot find ljscore collect2 ld returned 1 exit status 如何解决这个问题呢 这是 Qt 构建系统中自 4 7 0
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • Qt - 如何粘合两个窗口并将它们移动在一起?

    就像qmmp Qt 音乐播放器ui设计一样 这两个或三个窗口实际上在同一个窗口中 因为只有一个dock图标 并且这些窗口可以一起移动并相互附着 我看了源码 好像有用QDockWidget 但我真的不知道如何获得它的细节 当您手动移动辅助窗口
  • 如何在带有预编译头的项目中使用google protobuf

    我有一个包含多个项目的解决方案 我的项目 但不是全部 使用预编译头 我决定使用 protobuf 但遇到了一个问题 在 protoc exe 从 proto 生成 pb h 后 我尝试包含标头并收到错误 预编译标头未包含在 pb h 中 我
  • 禁用 QML Slider 的鼠标滚轮

    我希望能够滚动Flickable使用鼠标滚轮 或触摸板上的两根手指 不改变Sliders它可能包含 示例代码及结果应用 import QtQuick 2 7 import QtQuick Window 2 2 import QtQuick
  • 如何使用 Qtimer 添加 1 秒延迟

    我目前有一个方法如下 void SomeMethod int a Delay for one sec timer gt start 1000 After one sec SomeOtherFunction a 这个方法实际上是一个附加到信号
  • 为 Windows 98 编译 Qt

    我需要支持 Windows 98 Qt 文档声称这是可能的 但没有说明 Qt 4 6 的分布式二进制文件不能在 Win98 上运行 而且我采样的大多数 Qt 应用程序也不能在 Win98 上运行 对于几个确实在 98 上运行的应用程序 我询
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • QTimer 一点也不准确?

    运行在 Windows7 64 位机器上 具有非常强大的 CPU 8 核 16 线程 我使用 QTimer 以 50Hz 触发函数调用 但我最终得到了 30Hz 函数调用本身肯定需要不到 10 毫秒才能完成 整个过程发生在一个单独的线程中
  • 在 MacOS 终端上运行 ffmpeg [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我对 MacOS 相当陌生 我发现使用终端来获取信息并不容易ffmpeg和我在 Window 上一样正常运行 我有 ffmpeg 二进制文件ffmpe
  • Qt:如何连接到 SQLite?

    我安装了 SQLite3 解压到 c sqlite 创建了一个数据库 c sqlite mzsales 现在我试图在 QTableView 中显示其内容 QSqlDatabase db QSqlDatabase addDatabase QS

随机推荐

  • IDEA配置tomcat服务器

    需求背景 从Eclipse转IDEA后面对的第一个问题 就是要为IDEA配置tomcat服务 否则不可用 那么 功能需求 那么 该如何配置呢 1 点击 Edit Configurations 进入tomcat服务编辑页面 如下图所示 2 点
  • 漫谈数据库表设计及索引设计

    一 数据库表设计 在数据库表设计上有个很重要的设计准则 称为范式设计 什么是范式设计 范式来自英文Normal Form 简称NF MySQL是关系型数据库 但是要想设计 个好的关系 必须使关系满足一定的约束条件 此约束已经形成了规范 分成
  • 一阶RC低通滤波器(二)

    这篇文章补充下前面讲的一阶低通滤波器 在母线电压采样或是在电机的三相端电压采样时 往往是先分压 再经过RC低通滤波器 电路图如下 1 先求输出和输入的关系 Uao Ua 从上式可以看出系统相当于一个典型的一阶低通滤波器串联了一个R2 R1
  • python-opencv之形态学操作(腐蚀和膨胀)原理详解

    形态学操作作用 Removing noise Isolation of individual elements and joining disparate elements in an image Finding of intensity
  • frp login to server failed: i/o deadline reached

    使用kcp协议有时会出现这个问题 配置改为tcp即可
  • 【科研入门】会议、期刊、出版社、文献数据库、引文数据库、SCI分区、影响因子等基础科研必备知识

    大家好 我是洲洲 欢迎关注 一个爱听周杰伦的程序员 关注公众号 程序员洲洲 即可获得10G学习资料 面试笔记 大厂独家学习体系路线等 还可以加入技术交流群欢迎大家在CSDN后台私信我 本文目录 一 会议与期刊 二 如何辨别是否正规期刊or会
  • 进阶题解:链表相交,吊打代码随想录

    随想录解法 class Solution public ListNode getIntersectionNode ListNode headA ListNode headB ListNode curA headA ListNode curB
  • #pragma data_seg共享数据使用说明

    用 pragma data seg建立一个新的数据段并定义共享数据 其具体格式为 pragma data seg shareddata HWND sharedwnd NULL 共享数据 pragma data seg 1 pragma da
  • 样本方差为何除以n-1而不是n?

    很多人可能都会有疑问 为什么要除以n 1 而不是n 如果除以n 对样本方差的估计不是无偏估计 比总体方差要小 要想是无偏估计就要调小分母 所以除以n 1 那么问题来了 为什么不是除以n 2 n 3等 所以在这里彻底总结一下 首先交代一下无偏
  • wangEditor富文本编辑器+react+antd的使用

    1 github上发现富文本编辑器 官网地址及github地址 2 结合react antd的具体使用 案例使用场景 MyModal为弹窗 弹窗显示 编辑名称及描述 描述使用wangeditor富文本编辑器实现 MyModal js imp
  • 免费的HTML5连载来了《HTML5网页开发实例详解》连载(六)媒体查询

    响应式设计的另一个重要技术手段是媒体查询 如果只是简单的设计一个流式布局系统 那么可以保证每个网格按比例的放大和缩小 但有可能会使得在小屏幕下 如手机设备 网格太小而严重影响阅读 这样的设计称不上响应式设计 媒体查询可以来解决这一问题 媒体
  • VMware workstation 14.1.8 pro 下载地址 14最新版

    VMware Workstation 14 1 8 Pro 发布于2019年11月12日 官网下载地址如下 https download3 vmware com software wkst file VMware workstation f
  • linux如何查看安装了哪些软件

    linux查看安装了哪些软件的方法 1 利用 rpm qa 命令查看rpm方法安装的软件 2 利用 dpkg l 命令查看deb方法安装的软件 3 利用 yum list installed 命令查看yum方法安装的软件 本教程操作环境 l
  • python爬虫笔记

    python爬虫笔记 找到了一个网址 https blog csdn net belalds article details 80694126 1 使用requests库 import requests 导入requests库 respon
  • MetaMask 添加BSC、Polygon网络配置

    打开浏览器 点击MetaMask插件 选择网络 点击弹窗中的 Add Network 按钮 添加各网络配置如下 1 BSC Binance Smart Chain 主网 key value 网络名称 Network Name Binance
  • python3爬虫 selenium+pyquery爬取人才网简历实战

    不废话 直接贴代码 各位看官要是觉得可以的话 麻烦点个赞 import requests pymysql pyquery time from bs4 import BeautifulSoup from selenium import web
  • 【2022年第十三届蓝桥杯省赛个人题解】

    A 九进制转十进制 5分 题目描述 九进制正整数 2022 9 2022 9 2022 9 转换成十进制等于多少 AC代码 include
  • 【数据结构】HashMap

    文章目录 参数 DEFAULT INITIAL CAPACITY MAXIMUM CAPACITY loadFactor initialCapacity threshold 方法 tableSizeFor hash 参数 DEFAULT I
  • Python+selenium的web自动化—PageObject模式解析及案例

    一 PO模式 Page Object 简称PO 模式 是Selenium实战中最为流行 并且是自动化测试中最为熟悉和推崇的一种设计模式 在设计自动化测试时 把页面元素和元素的操作方法按照页面抽象出来 分离成一定的对象 然后再进行组织 做we
  • Qt 绘制炫彩时钟

    录制 2022 09 15 09 44 58 720 思路 1 使用定时器 每秒给 秒值 增加 1 当 秒值 等于 60 时 给 分值 增加1 当分值为60时 给 时值 加1 2 绘制界面时 可以用信号槽触发 也可以调用函数触发 我这里用的