QPainter - 八卦时钟

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FFmpeg常见命令行(五):FFmpeg滤镜使用

前言 在Android音视频开发中&#xff0c;网上知识点过于零碎&#xff0c;自学起来难度非常大&#xff0c;不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》&#xff0c;结合我自己的工作学习经历&#xff0c;我准备写一个音视频系列blog。本文是音视频系…

2023年中国日志审计市场竞争格局、市场规模、下游应用领域及行业发展趋势[图]

日志是行为或状态详细描述的载体&#xff0c;其时效性与信息丰富程度在网络安全事件分析、事件回溯和取证过程中起到重要作用。在法律层&#xff0c;日志也是重要的电子证据&#xff0c;日志记录、监控、审计手段等&#xff0c;可以帮助有效地减少信息破坏、信息泄露的问题&…

【Python机器学习】实验10 支持向量机

文章目录 支持向量机实例1 线性可分的支持向量机1.1 数据读取1.2 准备训练数据1.3 实例化线性支持向量机1.4 可视化分析 实例2 核支持向量机2.1 读取数据集2.2 定义高斯核函数2.3 创建非线性的支持向量机2.4 可视化样本类别 实例3 如何选择最优的C和gamma3.1 读取数据3.2 利用数…

断路器分合闸速度试验

试验目的 高压断路器的分、 合闸速度是断路器的重要特性参数, 反映出断路器的操动机构 与传动机构在分、 合闸过程中的运动特征。 断路器分、 合闸速度超出或者低于规定值 均会影响断路器的运行状态和使用寿命。 断路器合闸速度不足, 将会引起触头合闸振颤, 预击穿时间过长。 断…

Java课题笔记~ Request请求

1.请求消息格式 客户端发送一个HTTP请求到服务器的请求消息包括以下格式&#xff1a; 请求行&#xff08;request line&#xff09;、请求头部&#xff08;header&#xff09;、空行和请求数据四个部分组成。下图给出了请求报文的一般格式。 GET请求&#xff1a; POST请求&am…

机器学习笔记:李宏毅ChatGPT:生成式学习的两种策略

1 策略1 “各个击破”——autoregressive model “各个击破”——一个一个生成出来 2 策略2 &#xff1a; “一次到位”——non-autoregressve model 一步到位&#xff0c;全部生成出来 2.1 non-autoregressive model 如何确定长度&#xff1f; 两种策略 策略1&#xff1a;始…

(十五)大数据实战——hive的安装部署

前言 Hive是由Facebook开源&#xff0c;基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张表&#xff0c;并提供类SQL查询功能。本节内容我们主要介绍一下hive的安装与部署的相关内容。 正文 上传hive安装包到hadoop101服务器/opt/software目录 解…

无涯教程-Perl - link函数

描述 此函数创建一个新文件名NEWFILE,链接到文件OLDFILE。该函数创建一个硬链接&#xff1b;如果需要符号链接,请使用符号链接功能。 语法 以下是此函数的简单语法- link OLDFILE,NEWFILE返回值 如果失败,此函数返回0,如果成功,则返回1。 例 以下是显示其基本用法的示例…

IPC之三:使用 System V 消息队列进行进程间通信的实例

IPC 是 Linux 编程中一个重要的概念&#xff0c;IPC 有多种方式&#xff0c;本文主要介绍消息队列(Message Queues)&#xff0c;消息队列可以完成同一台计算机上的进程之间的通信&#xff0c;相比较管道&#xff0c;消息队列要复杂一些&#xff0c;但使用起来更加灵活和方便&am…

Android界面设计与用户体验

Android界面设计与用户体验 1. 引言 在如今竞争激烈的移动应用市场&#xff0c;提供优秀的用户体验成为了应用开发的关键要素。无论应用功能多么强大&#xff0c;如果用户界面设计不合理&#xff0c;用户体验不佳&#xff0c;很可能会导致用户流失。因此&#xff0c;在Androi…

BI技巧丨利用Index计算半累计

在实际的业务场景中&#xff0c;特别是财务模块和库存管理模块&#xff0c;经常需要我们针对每个月的期初期末进行相关指标计算&#xff0c;这也是我们之前曾经提到的Calculate基础应用——半累计计算。 现在我们也可以通过微软新推出的Index开窗函数来解决这一问题。 INDEX函…

kafka:java client使用总结塈seek() VS commitSync()的区别(三)

最近一段日子接触了kafka这个消息系统&#xff0c;主要为了我的开源中间件项目simplemq增加kafka支持&#xff08;基于kafka-client【java】&#xff09;&#xff0c;如今总算完成&#xff0c;本文是对这个过程中对kafka消息系统的使用总结 线程安全 关于线程安全&#xff0c…

java 自定义xss校验注解实现

自定义一个注解Xss。名字随意 import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Targe…

推出 Elasticsearch 查询语言 (ES|QL)

作者&#xff1a;Costin Leau 我很高兴地宣布&#xff0c;经过大约一年的开发&#xff0c;Elasticsearch 查询语言 (ES|QL) 已准备好与世界共享&#xff0c;并已登陆 Elasticsearch 存储库。 ES|QL 是 Elasticsearch 原生的强大声明性语言&#xff0c;专为可组合性、表现力和速…

DP1.4接口的PCB布局布线要求

DP接口即为DisplayPort接口&#xff0c;是由视频电子标准协会发布的显示接口。DP接口将在传输视频信号的同时加入对高清音频信号传输的支持&#xff0c;并且同时支持更高的分辨率以及刷新率。DP1.4通信端口规范新标准基于DP1.3规范&#xff0c;宽度不变但加入了显示压缩流技术&…

PAT1044 Shopping in Mars

个人学习记录&#xff0c;代码难免不尽人意。 做了这么多题难得本题不看答案一遍过&#xff0c;很是激动。 Shopping in Mars is quite a different experience. The Mars people pay by chained diamonds. Each diamond has a value (in Mars dollars M$). When making the pa…

opencv基础46-图像金字塔02-拉普拉斯金字塔

前面我们介绍了高斯金字塔&#xff0c;高斯金字塔是通过对一幅图像一系列的向下采样所产生的。有时&#xff0c;我们希望通过对金字塔中的小图像进行向上采样以获取完整的大尺寸高分辨率图像&#xff0c;这时就需要用到拉普拉斯金字塔 前面我们已经介绍过&#xff0c;一幅图像在…

Elasticsearch:如何创建 Elasticsearch PEM 和/或 P12 证书?

你是否希望使用 SSL/TLS 证书来保护你的 Elasticsearch 部署&#xff1f; 在本文中&#xff0c;我们将指导你完成为 Elasticsearch 创建 PEM 和 P12 证书的过程。 这些证书在建立安全连接和确保 Elasticsearch 集群的完整性方面发挥着至关重要的作用。 友情提示&#xff1a;你可…

vue3 + vite + ts 封装 SvgIcon组件

环境 vite vue3 ts "vue": "^3.3.4", "vite": "^4.4.0", "typescript": "^5.0.2",# 需要下载的依赖 "vite-plugin-svg-icons": "^2.0.1",不同版本可能存在一定差异, 这篇文章不可能对应所…

一个概率论例题引发的思考

浙江大学版《概率论与梳理统计》一书中的&#xff0c;第13章第1节例2如下&#xff1a; 这个解释和模型比较简单易懂。接下来&#xff0c;第2节的例2是一个关于此模型的题目&#xff1a; 在我自己的理解中&#xff0c;此题的解法跟上一个题目一样&#xff0c;第二级传输后&…