#include "Qiankunmap.h"
#include <QtDebug>
#include <QPainter>
#include <QPainterPath>
#include <QStaticText>
#include <QHoverEvent>
#include <QTimer>
#include <cmath>
static auto angle_8_1 = 360.0 / 8.0;
static auto angle_24_1 = 360.0 / 24.0;
static auto angle_32_1 = 360.0 / 32.0;
//渐变背景颜色结构体
typedef struct GRADIENTCOLOR_DATAS_{
double fBkgndAngleVal; //渐变背景角度从0到1
QColor cBkgndAngleClr; //渐变背景当前角度颜色
}GRADIENTCOLOR_DATAS,*PGRADIENTCOLOR_DATAS;
static QList<std::u16string> sTianGanChar ={u"乾",u"巽",u"坎",u"艮",u"坤",u"震",u"离",u"兑"};
static QList<std::u16string> sSolarsTerms={u"冬至",u"小寒",u"大寒",u"立春",u"雨水",u"惊蛰",u"春分",u"清明",u"谷雨",u"立夏",u"小满",u"芒种",
u"夏至",u"小暑",u"大暑",u"立秋",u"处暑",u"白露",u"秋分",u"寒露",u"霜降",u"立冬",u"小雪",u"大雪"};
static QList<std::u16string> sElementsTwo={u"丙丁火",u"已坤土",u"庚辛金",u"乾阳金",u"壬癸水",u"戊艮土",u"甲乙木",u"巽风木"};
static QList<std::u16string> sElementsOne={u"午火",u"未土",u"申金",u"酉金",u"戌土",u"亥水",u"子水",u"丑土",u"寅木",u"卯木",u"辰土",u"巳水"};
static QList<std::u16string> sTianGanDiz={u"子",u"壬",u"丑",u"癸",u"寅",u"艮",u"卯",u"甲",u"辰",u"乙",u"巳",u"巽",u"午",u"丙",u"未",u"丁",u"申",u"坤",u"酉",u"庚",u"戌",u"辛",u"亥",u"乾"};
static QList<GRADIENTCOLOR_DATAS> vBkgColorsList = {{0, QColor(35, 40, 3, 255)},{0.16, QColor(136, 106, 22, 255)},{0.225, QColor(166, 140, 41, 255)},
{0.285, QColor(204, 181, 74, 255)},{0.345, QColor(235, 219, 102, 255)},{0.415, QColor(245, 236, 112, 255)},
{0.52, QColor(209, 190, 76, 255)},{0.57, QColor(187, 156, 51, 255)},{0.635, QColor(168, 142, 42, 255)},
{0.695, QColor(202, 174, 68, 255)},{0.75, QColor(218, 202, 86, 255)},{0.815, QColor(208, 187, 73, 255)},
{0.88, QColor(187, 156, 51, 255)},{0.935, QColor(137, 108, 26, 255)},{1, QColor(35, 40, 3, 255)}}; //渐变背景颜色集合
Qiankunmap::Qiankunmap(QWidget *parent)
: QWidget(parent)
{
resize(600, 600);
timer_ = new QTimer(this);
connect(timer_, &QTimer::timeout, this, &Qiankunmap::onTimer);
timer_->start(30);
}
void Qiankunmap::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent(event);
QPainter painter(this);
painter.fillRect(rect(), Qt::white);
painter.setRenderHints(QPainter::Antialiasing);
// 移动当前的坐标系到绘制的中心,这样便于坐标计算
painter.translate(QPointF(width()/ 2.0 , height() / 2.0));
auto radius = std::min(this->width(), this->height()) / 2.0;
// 从外层到内的圆环占据整个绘制的比例
auto radius_1 = radius * (300.0 - 10.000) / 300.0;
auto radius_2 = radius * (300.0 - 60.00) / 300.0;
auto radius_3 = radius * (300.0 - 120.0) / 300.0;
auto radius_4 = radius * (300.0 - 150.0) / 300.0;
auto radius_5 = radius * (300.0 - 190.0) / 300.0;
auto radius_6 = radius * (300.0 - 220.0) / 300.0;
auto radius_7 = radius * (300.0 - 250.0) / 300.0; // 鱼圆圈
painter.save();
painter.setPen(Qt::NoPen);
QConicalGradient coneGradient(0, 0, 180.0);
int sCount=vBkgColorsList.count();
for(int s=0;s<sCount;s++){
coneGradient.setColorAt(vBkgColorsList[s].fBkgndAngleVal,vBkgColorsList[s].cBkgndAngleClr);
}
painter.setBrush(coneGradient);
painter.drawEllipse(-radius, -radius, radius * 2, radius * 2);
painter.restore();
drawYinYangFish(&painter, radius_7);
drawGua(&painter, radius_6);
drawGuaCharacter(&painter, radius_5, radius_6);
drawCircle(&painter, radius_5, QColor(0x808000), 3.0);
drawTianGanWith5Elements(&painter, radius_4, radius_5);
drawCircle(&painter, radius_4, QColor(0x808000), 3.0);
drawDiZhiWith5Elements(&painter, radius_3, radius_4);
drawCircle(&painter, radius_3, QColor(0xDC143C), 3.0);
drawTianGanDiZhi(&painter, radius_2, radius_3);
drawCircle(&painter, radius_2, QColor(Qt::black), 2.0);
draw24SolarTerms(&painter, radius_1, radius_2);
drawCircle(&painter, radius_1, QColor(0x834447), 6.0);
drawOneEighthSeperator(&painter, radius_1, radius_7);
drawOneTwentyFourthSeperator(&painter, radius_1, radius_3);
drawQuarterSeperator(&painter, radius_3, radius_4);
}
void Qiankunmap::drawYinYangFish(QPainter *painter, qreal radius)
{
auto diameter = 2.0 * radius;
painter->save();
painter->setPen(Qt::black);
painter->setBrush(Qt::black);
painter->drawEllipse(QRectF(-radius, -radius, diameter, diameter));
painter->restore();
// white fish head
auto fishHeadRadius = radius / 2.0f;
QPainterPath path(QPointF(0.0f, -radius));
path.arcTo(QRectF(-radius, -radius, diameter, diameter), 90.0, 180.0);
path.arcTo(QRectF(-fishHeadRadius, 0.0, radius, radius), -90.0, -180.0);
path.arcTo(QRectF(-fishHeadRadius, -radius, radius, radius), -90.0, 180.0);
painter->save();
painter->setPen(QPen(QColor(Qt::black), 2.0));
painter->drawPath(path); // he he
painter->fillPath(path, Qt::white);
painter->restore();
// white fish eye
auto fishEyeWidth = radius / 2.5f;
painter->save();
painter->setPen(QPen(QBrush(Qt::black), fishEyeWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter->drawPoint(QPointF(0.0f, -radius / 2.0f));
painter->restore();
// black fish eye
painter->save();
painter->setPen(QPen(QBrush(Qt::white), fishEyeWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter->drawPoint(QPointF(0.0f, radius / 2.0f));
painter->restore();
}
void Qiankunmap::drawGua(QPainter *painter, qreal radius)
{
painter->save();
painter->rotate(degree_);
auto penWidth = 4.0;
static auto spacerAngle = angle_8_1 / 8.0;
static auto rightStartAngle = (angle_8_1 + angle_8_1 / 2.0 + spacerAngle) * 16;
static auto leftStartAngle = (90.0 + spacerAngle) * 16;
static auto spanAngleFull = (angle_8_1 - 2 * spacerAngle) * 16;
static auto spanAngleHalf = (angle_8_1 / 2.0 - 2 * spacerAngle) * 16;
auto drawer = [=](qreal angle, std::tuple<bool, QColor, QColor> top, std::tuple<bool, QColor, QColor> middle, std::tuple<bool, QColor, QColor> bottom){
painter->save();
painter->rotate(angle);
// top
if(std::get<0>(top)){
painter->save();
painter->setPen(QPen(QBrush(std::get<1>(top)), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter->drawArc(QRectF(-radius, -radius, 2 * radius, 2 * radius),
rightStartAngle,
spanAngleFull);
painter->restore();
}else{
painter->save();
painter->setPen(QPen(QBrush(std::get<1>(top)), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin));
painter->drawArc(QRectF(-radius, -radius, 2 * radius, 2 * radius),
rightStartAngle,
spanAngleHalf);
painter->restore();
painter->save();
painter->setPen(QPen(QBrush(std::get<2>(top)), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::MiterJoin));
painter->drawArc(QRectF(-radius, -radius, 2 * radius, 2 * radius),
leftStartAngle,
spanAngleHalf);
painter->restore();
}
// middle
auto radius_temp = radius - 2.0 * penWidth;
if(std::get<0>(middle)){
painter->save();
painter->setPen(QPen(QBrush(std::get<1>(middle)), penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter->drawArc(QRectF(-radius_temp, -radius_tem
QT,C++实现的天干地支八卦图源代码
需积分: 0 188 浏览量
更新于2022-02-19
2
收藏 6KB ZIP 举报
QT是Qt Company开发的一种跨平台应用程序开发框架,广泛用于创建桌面、移动和嵌入式平台的应用程序。在本文中,我们将深入探讨如何使用C++和QT库来实现一个天干地支八卦图。这个项目主要涉及到Qt的自绘功能,也就是通过编程方式控制图形界面的绘制,以展现中国传统文化中的天干地支和八卦图案。
让我们来看看`Qiankunmap.cpp`。这是项目的主体部分,包含了天干地支八卦图的具体实现逻辑。在C++中,我们通常会定义类的方法来处理图形的绘制和更新。可能包括初始化八卦图的各个元素,计算位置,以及根据用户交互进行重绘等操作。在QT中,我们可以继承`QWidget`或`QGraphicsView`等类,覆盖其`paintEvent()`方法,来实现自定义的绘图逻辑。
`main.cpp`是项目的入口点,负责创建并显示主窗口。在这里,我们需要实例化我们的自定义控件(如`Qiankunmap`),并将其添加到布局中。通常,我们还会设置窗口大小,添加菜单栏或工具栏,以及处理用户事件等。
`Qiankunmap.h`是头文件,声明了`Qiankunmap`类及其成员函数。在C++中,头文件用于提供类和其他实体的接口,以便其他源文件可以使用它们。`Qiankunmap`类可能包含构造函数,绘图方法,以及可能的属性和信号槽来响应用户交互。
`Bagua.pro`是QT项目的配置文件,它包含了项目的编译和链接设置。这里可能会指定QT库的版本,使用的模块(如`QT += gui`、`QT += widgets`),源文件列表,目标执行文件名,以及任何附加的编译器选项。
在实现天干地支八卦图时,开发者需要对八卦的排列和天干地支的循环规则有深入了解。八卦图由乾、坤、震、巽、坎、离、艮、兑八个卦象组成,而天干地支包括十天干(甲、乙、丙、丁、戊、己、庚、辛、壬、癸)和十二地支(子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥)。开发者需要将这些元素以特定的布局绘制在界面上,同时考虑到旋转、缩放和鼠标点击事件等交互功能。
总结来说,这个项目是一个结合了C++编程语言、QT库和中国传统文化的实践案例。通过实现`Qiankunmap`类,开发者不仅锻炼了QT自绘的能力,也对中国传统文化的可视化表达有了深入的理解。对于学习QT和C++的开发者而言,这是一个很好的学习资源,可以帮助他们掌握GUI编程和自定义控件的设计。
黑太狼大王
- 粉丝: 154
- 资源: 1
最新资源
- 串联式、并联式、混联式混合动力系统simulink控制策略模型(串联式、并联式、混联式每个都是独立的需要单独说拿哪个,默认是混联式RB) 有基于逻辑门限值、状态机的规则控制策略(RB)、基于等效燃油
- 法码滋.exe法码滋2.exe法码滋3.exe
- python-geohash-0.8.5-cp38-cp38-win-amd64
- Matlab根据flac、pfc或其他软件导出的坐标及应力、位移数据再现云图 案例包括导出在flac6.0中导出位移的fish代码(也可以自己先准备软件导出的坐标数据及对应点的位移或应力数据,可根据需
- 拳皇97.exe拳皇972.exe拳皇973.exe
- 捕鱼达人1.exe捕鱼达人2.exe捕鱼达人3.exe
- 医疗骨折摄像检测29-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma数据集合集.rar
- ks滑块加密算法与源代码
- 医护人员检测23-YOLOv8数据集合集.rar
- 1.电力系统短路故障引起电压暂降 2.不对称短路故障分析 包括:共两份自编word+相应matlab模型 1.短路故障的发生频次以及不同类型短路故障严重程度,本文选取三类典型的不对称短路展开研究