QPainter - 八卦时钟

news2025/3/16 6:06:54

QPainter - 八卦时钟

上一篇我们在画时钟的时候,已经把基本的钟表指针和刻度都绘制过了

想要完成八卦时钟,就要绘制这个里面的八卦了。

先上个图:

在这里插入图片描述

有人和我说八卦不能转

再来一张图:

在这里插入图片描述

背景的绘制

我们需要删除之前所绘制的白色背景, 并且将背景修改为黄色

我这里是直接使用的styleSheet设置的背景色

setStyleSheet("background-color:yellow;");

太极八卦的绘制

这里面是三部分:

  • 太极的绘制

太极的绘制我们添加绘制太极的函数.

太极的阴阳鱼就是一个半圆添加一个圆和裁减一个圆,我们使用QPainterPath很容易实现这个。

之后我们在给添加的圆的中心再绘制一个颜色相反的小圆作为鱼眼,这样即可完成阴阳鱼的绘制

void Universe::drawUniverse(QPainter &painter)
{
    int radius = radius_ * 0.2;
    painter.save();
    painter.rotate(-degree_);
    // 绘制阳鱼
    painter.setPen(Qt::NoPen);
    QPainterPath circle, tmp;
    // 这个后面的两个参数时开始度数和移动过的度数
    circle.arcTo(-radius, -radius, radius * 2, radius * 2, 270, 180);
    tmp.addEllipse(QPointF(0, -radius / 2), radius / 2, radius / 2);
    circle -= tmp;

    tmp.clear();
    tmp.addEllipse(QPointF(0, radius / 2), radius / 2, radius / 2);
    circle += tmp;
    painter.fillPath(circle, Qt::white);

    tmp.clear();
    tmp.addEllipse(QPointF(0, radius / 2), radius / 4, radius / 4);
    painter.fillPath(tmp, Qt::black);

    // 绘制阴鱼,与阳鱼是一样的
    circle.clear();
    circle.arcTo(-radius, -radius, radius * 2, radius * 2, 90, 180);
    tmp.clear();
    tmp.addEllipse(QPointF(0, -radius / 2), radius / 2, radius / 2);
    circle += tmp;

    tmp.clear();
    tmp.addEllipse(QPointF(0, radius / 2), radius / 2, radius / 2);
    circle -= tmp;
    painter.fillPath(circle, Qt::black);

    tmp.clear();
    tmp.addEllipse(QPointF(0, -radius / 2), radius / 4, radius / 4);
    painter.fillPath(tmp, Qt::white);
    painter.restore();
}
  • 八卦的绘制

八卦的绘制是比阴阳鱼更简单的,八卦对应的是八个方位,我们按照方位给加上对应的卦象即可,我这里给了卦象顺序和描述

void Universe::drawBagua(QPainter &painter)
{
    // 因为每个卦象不一样,因此需要单独去绘制,这里写了8个
    int bottom = - radius_ * 0.25;
    int lineLength = 12;
    int midLength = 2;
    int interval = 4;
    painter.setPen(QPen(Qt::red, 2));
    painter.save();
    // painter.rotate(degree_);
    /* 乾三连 */
    QPoint point(-lineLength / 2, bottom);
    QPoint point2(lineLength / 2, bottom);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval);
    point2 = QPoint(lineLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval * 2);
    point2 = QPoint(lineLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    /* 巽下断 */
    painter.rotate(45);
    point = QPoint(-lineLength / 2, bottom);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom );
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom);
    point2 = QPoint(lineLength / 2,  bottom );
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval);
    point2 = QPoint(lineLength / 2, bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval * 2);
    point2 = QPoint(lineLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    /* 坎中满 */
    painter.rotate(45);
    point = QPoint(-lineLength / 2, bottom);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom );
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom);
    point2 = QPoint(lineLength / 2,  bottom );
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval);
    point2 = QPoint(lineLength / 2, bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval * 2);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom - interval * 2);
    point2 = QPoint(lineLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    /* 艮覆碗 */
    painter.rotate(45);
    point = QPoint(-lineLength / 2, bottom);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom );
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom);
    point2 = QPoint(lineLength / 2,  bottom );
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom - interval);
    point2 = QPoint(lineLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval *2);
    point2 = QPoint(lineLength / 2, bottom - interval * 2);
    painter.drawLine(point, point2);
    /* 坤六断 */
    painter.rotate(45);
    point = QPoint(-lineLength / 2, bottom);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom );
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom);
    point2 = QPoint(lineLength / 2,  bottom );
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom - interval);
    point2 = QPoint(lineLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval * 2);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom - interval * 2);
    point2 = QPoint(lineLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    /* 震仰盂 */
    painter.rotate(45);
    point = QPoint(-lineLength / 2, bottom);
    point2 = QPoint(lineLength / 2,  bottom);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom - interval);
    point2 = QPoint(lineLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval * 2);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom - interval * 2);
    point2 = QPoint(lineLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    /* 离中虚 */
    painter.rotate(45);
    point = QPoint(-lineLength / 2, bottom);
    point2 = QPoint(lineLength / 2,  bottom);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom - interval);
    point2 = QPoint(lineLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval * 2);
    point2 = QPoint(lineLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    /* 兑上缼 */
    painter.rotate(45);
    point = QPoint(-lineLength / 2, bottom);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom);
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom);
    point2 = QPoint(lineLength / 2,  bottom);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval);
    point2 = QPoint(-lineLength / 4 + midLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(lineLength / 4 - midLength/2, bottom - interval);
    point2 = QPoint(lineLength / 2,  bottom - interval);
    painter.drawLine(point, point2);
    point = QPoint(-lineLength / 2, bottom - interval * 2);
    point2 = QPoint(lineLength / 2,  bottom - interval * 2);
    painter.drawLine(point, point2);
    painter.restore();
}
  • 外部文字的绘制

八卦外部的文字绘制不复杂,但是八角形坐标得算一下, 这里也是贴出代码,初中的三角函数知识,不做解释,如果不明白可以自己画画图

int radiusIn = 100 * 0.85;
int radiusOut = 100 * 1.15;
int radiusText = 100 * 0.5;
const QStringList list{"乾", "巽", "坎", "艮", "坤", "震", "离", "兑"};
double pointInX = qSin(M_PI /180.0 * 22.5) * radiusIn / 2;
double pointOutX = qSin(M_PI /180.0 * 22.5) * radiusOut / 2;
double pointInY = radiusIn / 2 * qCos(M_PI /180.0 * 22.5);
double pointOutY = radiusOut / 2 * qCos(M_PI /180.0 * 22.5);
void Universe::drawBaguaText(QPainter &painter)
{
    painter.save();
    // painter.rotate(degree_);
    painter.setPen(QPen(Qt::black, 1));
    for(int i = 0; i < 8; i++)
    {
        painter.drawLine(-pointInX, pointInY, pointInX, pointInY);
        painter.drawLine(-pointOutX, pointOutY, pointOutX, pointOutY);
        painter.drawLine(pointInX, pointInY, pointOutX, pointOutY);
        painter.drawText(QRectF(-5, -radiusText, 10, 10), Qt::AlignCenter,  list[i]);
        painter.rotate(45);
    }
    painter.restore();
    update();
}

至此我们完成了所有的绘制部分,之前绘制钟表的背景部分的代码可以删除,我们只留下刻度和指针的代码,对了给指针的中心加一个白色的点来模拟固定的小钉子,不然看着有点小难受。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/864496.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

攻防世界-web-getit

1. 题目描述 菜鸡发现这个程序偷偷摸摸在自己的机器上搞事情&#xff0c;它决定一探究竟。 获取到文件后&#xff0c;先查看文件信息 说明是一个可执行程序&#xff0c;没啥思路&#xff0c;先逆向 2. 思路分析 逆向后&#xff0c;找到main函数&#xff0c;查看逻辑 通过逆…

智安网络|网络安全:危机下的创新与合作

随着信息技术的迅猛发展和互联网的普及&#xff0c;我们进入了一个高度网络化的社会。网络在提供便利和连接的同时&#xff0c;也带来了许多安全隐患和挑战。 一、网络安全的危险 **1.数据泄露和隐私侵犯&#xff1a;**网络上的个人和机构数据存在遭受泄露和盗取的风险&#…

C#,入门教程(42)——各种括号“()[]{}<>“的用法总结

&#xff08;成对的&#xff09;括号是各种编程语言的核心要素。很多年前就想着写这样一篇专门关于各种括号的技术文章。一直未动笔&#xff0c;因为总想着偷懒&#xff0c;但凡有一个人写了&#xff0c;就无需我动手了。可惜的是&#xff0c;等了十多年&#xff0c;也没有出现…

集成接近和环境光传感器市场调查报告

集成接近和环境光传感器在单个传感器中集成接近和环境光感应功能。该传感器广泛应用于物联网 (IoT) 设备、消费电子产品和可穿戴设备&#xff0c;集成接近和环境光传感器可以自动调整屏幕亮度并根据接近情况打开/关闭屏幕&#xff0c;以降低设备功耗。集成接近和环境光传感器广…

【嵌入式学习笔记】嵌入式入门4——独立看门狗IWDG

1.IWDG简介 IWDG的全称&#xff1a;Independent watchdog&#xff0c;即独立看门狗&#xff0c;IWDG的本能&#xff1a;产生系统复位信号的计数器IWDG的特性&#xff1a;递减的计数器&#xff0c;时钟由独立的RC振荡器提供&#xff08;可在待机和停止模式下运行&#xff09; 看…

16bit、8 通道、500kSPS、 SAR 型 ADC——MS5188N

MS5188N 是 8 通道、 16bit 、电荷再分配逐次逼近型模数 转换器&#xff0c;采用单电源供电。 MS5188N 拥有多通道、低功耗数据采集系统所需的所有 组成部分&#xff0c;包括&#xff1a;无失码的真 16 位 SAR ADC &#xff1b;用于将输入配 置为单端输入&#xff0…

水力发电厂测量装置配置选型及厂用电管理系统

NB/T 10861-2021《水力发电厂测量装置配置设计规范》对水电厂的测量装置配置做了详细要求和指导。测量装置是水力发电厂运行监测的重要环节&#xff0c;水电厂的测量主要分为电气量测量和非电量测量。电气测量指使用电的方式对电气实时参数进行测量&#xff0c;包括电流、电压、…

linux下实现生产者和消费者 pv操作

线程同步与线程安全 生产者和消费者特点图示理解编程实现测试结果 生产者和消费者 特点 1.解耦:因为多了一个缓冲区&#xff0c;所以生产者和消费者并不直接相互调用&#xff0c;这样生产者和消费者的代码发生变化&#xff0c;都不会对对方产生影响。这样其实就是把生产者和消…

使用 Gradio 构建生成式 AI 应用程序(一): 图片内容读取app

今天我们来学习DeepLearning.AI的在线课程&#xff1a;Building Generative AI Applications with Gradio&#xff0c;该课程主要讲述利用gradio来部署机器学习算法应用程序, 今天我们来学习第一课&#xff1a;Image captioning app&#xff0c;该课程主要讲述如何从图片中读取…

优秀项目团队最突出的5项重要特征

一个优秀的开发团队&#xff0c;对于软件项目而言&#xff0c;其重要性不言而喻。否则项目团队一盘散沙&#xff0c;直接影响项目准时保质保量地交付。一般从大家的认可度来说&#xff0c;优秀团队最突出的特征&#xff0c;主要集中在以下几个方面&#xff1a; 1、目标明确 优秀…

oracle连表查询in后边跟另一张表中的字符串字段

今天在做通过in进行连表查询的时候发现以下问题记录下 我的需求是A,B两张表连接查询&#xff0c;A中有一个FOOD_TYPES字段 存的值类型为1&#xff0c;2&#xff0c;3 B表中的字段是FOOD_TYPE 存的是单个数字字符串 我需要where b.food_type in a.food_types 但是无论怎么写都…

Live800:客服常用的6大提问技巧,帮助客服服务更高效

作为企业最前线的客服&#xff0c;提升服务质量是必须要做到的&#xff0c;而如何提升服务质量呢&#xff1f;其中一项关键点就是提问技巧。在客户沟通中&#xff0c;提问的方式和技巧直接影响着客户对企业服务的满意度。下面&#xff0c;本文将介绍客服常用的6大提问技巧&…

go语言的database/sql结合squirrel工具sql生成器完成数据库操作

database/sql database/sql是go语言内置数据库引擎&#xff0c;使用sql查询数据库&#xff0c;配置datasource后使用其数据库操作方法对数据库操作&#xff0c;如下&#xff1a; package mainimport ("database/sql""fmt"_ "github.com/Masterminds…

Android简单封装Matrix工具类

Android简单封装Matrix工具类 1.简介&#xff1a; Matrix 是一款微信研发并日常使用的应用性能接入框架&#xff0c;支持iOS, macOS和Android。 Matrix 通过接入各种性能监控方案&#xff0c;对性能监控项的异常数据进行采集和分析&#xff0c;输出相应的问题分析、定位与优化…

整数中1出现的次数(从1到n整数中1出现的次数)

解题思路1&#xff1a; 设定整数点&#xff08;如1、10、100等等&#xff09;作为位置点i&#xff08;对应n的各位、十位、百位等等&#xff09;&#xff0c;分别对每个数位上有多少包含1的点进行分析。 第一步&#xff1a;对n进行分割&#xff0c;分为两部分&#xff1a;高位…

JavaWeb学习|JavaBean;MVC三层架构;Filter;Listener

1.JavaBean 实体类 JavaBean有特定的写法: 必须要有一个无参构造 属性必须私有化。 必须有对应的get/set方法 用来和数据库的字段做映射 ORM; ORM:对象关系映射 表--->类 字段-->属性 行记录---->对象 2.<jsp&#xff1a;useBean 标签 3. MVC三层架构 4. Filter …

力扣301周赛C~DABC299 D、E、G

第 301 场周赛 C&#xff1a; 思路&#xff1a; 经典双指针问题&#xff0c;用i表示字符串start当前枚举到的位置&#xff0c;用j表示字符串target当前枚举到的位置&#xff1a; i从当前位置向后跑&#xff0c;跑到start串下标i之后的第一个不为_的位置 j从当前位置向后跑&a…

C语言属刷题训练【第八天】

文章目录 &#x1fa97;1、如下程序的运行结果是&#xff08; &#xff09;&#x1f4bb;2、若有定义&#xff1a; int a[2][3]; &#xff0c;以下选项中对 a 数组元素正确引用的是&#xff08; &#xff09;&#x1f9ff;3、在下面的字符数组定义中&#xff0c;哪一个有语法错…

JavaScript、TypeScript、ES5、ES6之间的联系和区别

ECMAScript&#xff1a; 一个由 ECMA International 进行标准化&#xff0c;TC39 委员会进行监督的语言。通常用于指代标准本身。JavaScript&#xff1a; ECMAScript 标准的各种实现的最常用称呼。这个术语并不局限于某个特定版本的 ECMAScript 规范&#xff0c;并且可能被用于…

k8s RBAC授权普通系统用户对namespace访问权限

背景&#xff1a;最近遇到一个问题&#xff0c;那就是需要给别人共享一下 Kubernetes 的某个资源的使用和访问权限&#xff0c;这个仅仅存在于某个 namespace 下&#xff0c;但是我又不能把管理员权限全都给它&#xff0c;我想只给他授予这一个 Namespace 下的权限&#xff0c;…