目录
1. ConnectionStyle类实现
这段代码的主要目的是定义了一个连接样式的类,用于加载、存储和管理连接的外观配置信息。它包含了构造函数、加载和保存配置信息的方法,以及一些用于获取特定属性值的函数。此外,还包含了一些用于检查和处理JSON数据的宏和条件编译的调试功能。
ConnectionStyle.hpp
#pragma once
#include <QtGui/QColor>
#include "Export.hpp" // 用于导出类,以便其他模块或库可以访问 ConnectionStyle 类。
#include "Style.hpp" // 用于继承 Style 类
namespace QtNodes {
class NODE_EDITOR_PUBLIC ConnectionStyle : public Style
{
public:
ConnectionStyle(); // 默认构造函数的声明
ConnectionStyle(QString jsonText); // 带有参数的构造函数的声明, JSON文本字符串作为参数
~ConnectionStyle() = default;
public:
// 静态成员函数的声明,用于设置连接样式,JSON 文本字符串作为参数。
// 可直接类名调用
static void setConnectionStyle(QString jsonText);
public:
// 虚函数的声明,实现父类中纯虚函数,用于加载《连接》样式的配置信息
void loadJson(QJsonObject const &json) override;
// 虚函数的声明,用于将连接样式的配置信息转换为 JSON 对象。
QJsonObject toJson() const override;
public:
// 一系列的成员函数的声明,用于获取不同连接样式属性的值,
// 如构造连接颜色、正常连接颜色、选定连接颜色等。
QColor constructionColor() const;
QColor normalColor() const;
QColor normalColor(QString typeId) const;
QColor selectedColor() const;
QColor selectedHaloColor() const;
QColor hoveredColor() const;
// 线宽
float lineWidth() const;
float constructionLineWidth() const;
float pointDiameter() const;
bool useDataDefinedColors() const;
private:
// 一系列的私有成员变量的声明,用于存储连接样式的不同属性值,如颜色、线宽等。
// 各种颜色
QColor ConstructionColor;
QColor NormalColor;
QColor SelectedColor;
QColor SelectedHaloColor;
QColor HoveredColor;
// 线宽
float LineWidth;
float ConstructionLineWidth;
float PointDiameter;
bool UseDataDefinedColors;
};
} // namespace QtNodes
ConnectionStyle.cpp
#include "ConnectionStyle.hpp"
#include "StyleCollection.hpp" // 用于设置风格StyleCollection::setConnectionStyle(style);
#include <QtCore/QJsonArray>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonValueRef>
#include <QDebug>
#include <random>
using QtNodes::ConnectionStyle;
// 确保静态资源(图片文件,json文件等)的正确加载
// 如果你有一个名为 myapp.qrc 的资源文件,那么你可以在代码中使用 Q_INIT_RESOURCE(myapp);
// 这句代码,写在类的构造函数中,可确保在静态链接的情况下将资源链接到
// 最终的应用程序二进制文件中;写在main函数中,则全局可以使用。
// 同理,在将资源卸载的时候,需要调用Q_CLEANUP_RESOURCE()。
inline void initResources() // 在ConnectionStyle构造函数中被调用
{
Q_INIT_RESOURCE(resources); // 用于初始化Qt资源系统的语句
}
// 默认构造函数的定义。在这个构造函数中,会调用initResources()来初始化资源,
// 然后通过调用loadJsonFile(":DefaultStyle.json")加载默认的样式配置。
ConnectionStyle::ConnectionStyle()
{
// Explicit resources inialization for preventing the static initialization
// order fiasco: https://isocpp.org/wiki/faq/ctors#static-init-order
initResources();
// This configuration is stored inside the compiled unit and is loaded statically
loadJsonFile(":DefaultStyle.json");
}
// 带有参数的构造函数的定义。这个构造函数接受一个JSON文本字符串作为参数,
// 它会加载默认的样式配置并从传入的JSON文本中加载额外的配置。
ConnectionStyle::ConnectionStyle(QString jsonText)
{
loadJsonFile(":DefaultStyle.json"); // 继承自父类Style,父类有个纯虚函数loadJson,被子类ConnectionStyle实现,并对自己的私有成员变量赋值。
loadJsonText(jsonText);
}
// 定义了一个用于从JSON对象加载连接样式配置的函数。
// 这个函数根据JSON对象的键值对,解析并设置连接样式的各个属性。
void ConnectionStyle::setConnectionStyle(QString jsonText)
{
ConnectionStyle style(jsonText);
StyleCollection::setConnectionStyle(style);
}
// 一系列用于读取和写入颜色、浮点数和布尔值的宏。
// 这些宏用于将连接样式的不同属性从JSON对象中读取和写入。
#ifdef STYLE_DEBUG
#define CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(v, variable) \
{ \
if (v.type() == QJsonValue::Undefined || v.type() == QJsonValue::Null) \
qWarning() << "Undefined value for parameter:" << #variable; \
}
#else
#define CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(v, variable)
#endif
#define CONNECTION_VALUE_EXISTS(v) \
(v.type() != QJsonValue::Undefined && v.type() != QJsonValue::Null)
#define CONNECTION_STYLE_READ_COLOR(values, variable) \
{ \
auto valueRef = values[#variable]; \
CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(valueRef, variable) \
if (CONNECTION_VALUE_EXISTS(valueRef)) { \
if (valueRef.isArray()) { \
auto colorArray = valueRef.toArray(); \
std::vector<int> rgb; \
rgb.reserve(3); \
for (auto it = colorArray.begin(); it != colorArray.end(); ++it) { \
rgb.push_back((*it).toInt()); \
} \
variable = QColor(rgb[0], rgb[1], rgb[2]); \
} else { \
variable = QColor(valueRef.toString()); \
} \
} \
}
#define CONNECTION_STYLE_WRITE_COLOR(values, variable) \
{ \
values[#variable] = variable.name(); \
}
#define CONNECTION_STYLE_READ_FLOAT(values, variable) \
{ \
auto valueRef = values[#variable]; \
CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(valueRef, variable) \
if (CONNECTION_VALUE_EXISTS(valueRef)) \
variable = valueRef.toDouble(); \
}
#define CONNECTION_STYLE_WRITE_FLOAT(values, variable) \
{ \
values[#variable] = variable; \
}
#define CONNECTION_STYLE_READ_BOOL(values, variable) \
{ \
auto valueRef = values[#variable]; \
CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(valueRef, variable) \
if (CONNECTION_VALUE_EXISTS(valueRef)) \
variable = valueRef.toBool(); \
}
#define CONNECTION_STYLE_WRITE_BOOL(values, variable) \
{ \
values[#variable] = variable; \
}
// 实现父类中纯虚函数,用于加载《连接》样式的配置信息
void ConnectionStyle::loadJson(QJsonObject const &json)
{
QJsonValue nodeStyleValues = json["ConnectionStyle"];
QJsonObject obj = nodeStyleValues.toObject();
CONNECTION_STYLE_READ_COLOR(obj, ConstructionColor);
CONNECTION_STYLE_READ_COLOR(obj, NormalColor);
CONNECTION_STYLE_READ_COLOR(obj, SelectedColor);
CONNECTION_STYLE_READ_COLOR(obj, SelectedHaloColor);
CONNECTION_STYLE_READ_COLOR(obj, HoveredColor);
CONNECTION_STYLE_READ_FLOAT(obj, LineWidth);
CONNECTION_STYLE_READ_FLOAT(obj, ConstructionLineWidth);
CONNECTION_STYLE_READ_FLOAT(obj, PointDiameter);
CONNECTION_STYLE_READ_BOOL(obj, UseDataDefinedColors);
}
// 定义了一个将连接样式配置转换为JSON对象的函数。
// 这个函数创建一个JSON对象,将连接样式的各个属性存储在对象中,并返回该对象。
QJsonObject ConnectionStyle::toJson() const
{
QJsonObject obj;
// 将连接样式的各个属性存储在JSON对象中
CONNECTION_STYLE_WRITE_COLOR(obj, ConstructionColor);
CONNECTION_STYLE_WRITE_COLOR(obj, NormalColor);
CONNECTION_STYLE_WRITE_COLOR(obj, SelectedColor);
CONNECTION_STYLE_WRITE_COLOR(obj, SelectedHaloColor);
CONNECTION_STYLE_WRITE_COLOR(obj, HoveredColor);
CONNECTION_STYLE_WRITE_FLOAT(obj, LineWidth);
CONNECTION_STYLE_WRITE_FLOAT(obj, ConstructionLineWidth);
CONNECTION_STYLE_WRITE_FLOAT(obj, PointDiameter);
CONNECTION_STYLE_WRITE_BOOL(obj, UseDataDefinedColors);
QJsonObject root; // JSON对象
root["ConnectionStyle"] = obj; // 将json对象放置在root json对象的其中一个成员
return root;
}
// 定义了一个返回连接的颜色的函数。
QColor ConnectionStyle::constructionColor() const
{
return ConstructionColor;
}
// 返回正常连接的颜色的函数。
QColor ConnectionStyle::normalColor() const
{
return NormalColor;
}
// 定义了一个返回特定类型的正常连接颜色的函数,根据传入的类型ID生成颜色。
QColor ConnectionStyle::normalColor(QString typeId) const
{
std::size_t hash = qHash(typeId);
std::size_t const hue_range = 0xFF;
std::mt19937 gen(static_cast<unsigned int>(hash));
std::uniform_int_distribution<int> distrib(0, hue_range);
int hue = distrib(gen);
int sat = 120 + hash % 129;
return QColor::fromHsl(hue, sat, 160);
}
// 选定连接颜色的函数
QColor ConnectionStyle::selectedColor() const
{
return SelectedColor;
}
// 选定连接光晕颜色的函数
QColor ConnectionStyle::selectedHaloColor() const
{
return SelectedHaloColor;
}
// 悬停连接颜色的函数
QColor ConnectionStyle::hoveredColor() const
{
return HoveredColor;
}
// 返回线宽的函数。
float ConnectionStyle::lineWidth() const
{
return LineWidth;
}
// 返回构造线宽的函数。
float ConnectionStyle::constructionLineWidth() const
{
return ConstructionLineWidth;
}
// 返回点直径的函数。
float ConnectionStyle::pointDiameter() const
{
return PointDiameter;
}
// 定义了一个返回是否使用数据定义颜色的函数,用于判断是否启用了数据定义的颜色。
bool ConnectionStyle::useDataDefinedColors() const
{
return UseDataDefinedColors;
}
2. 定制连接风格
调用形式
// 设置风格
setStyle();
static void setStyle()
{
// 字符串前面加R,则该字符串是原始字符串,里面的都是普通字符。
// 连接风格设置内容:
// "ConstructionColor": "gray",
// "NormalColor" : "black",
// "SelectedColor" : "gray",
// "SelectedHaloColor" : "deepskyblue",
// "HoveredColor" : "deepskyblue",
//
// "LineWidth" : 3.0,
// "ConstructionLineWidth" : 2.0,
// "PointDiameter" : 10.0,
//
// "UseDataDefinedColors" : true
ConnectionStyle::setConnectionStyle(
R"(
{
"ConnectionStyle": {
"ConstructionColor": "gray",
"NormalColor": "black",
"SelectedColor": "gray",
"SelectedHaloColor": "deepskyblue",
"HoveredColor": "deepskyblue",
"LineWidth": 3.0,
"ConstructionLineWidth": 2.0,
"PointDiameter": 10.0,
"UseDataDefinedColors": true
}
}
)");
}
// 两步:
// (1) 使用QString jsonTexts创建ConnectionStyle对象style
// (2) 然后在风格集合类StyleCollection设置连接风格为style
void ConnectionStyle::setConnectionStyle(QString jsonText)
{
ConnectionStyle style(jsonText); // 首先载入默认配置,再增加新增配置
StyleCollection::setConnectionStyle(style); // 内部生成一个单例静态对象
}
QString 传入的键值对,以json格式查看
3. 默认配置
{
"GraphicsViewStyle": {
"BackgroundColor": [53, 53, 53],
"FineGridColor": [60, 60, 60],
"CoarseGridColor": [25, 25, 25]
},
"NodeStyle": {
"NormalBoundaryColor": [255, 255, 255],
"SelectedBoundaryColor": [255, 165, 0],
"GradientColor0": "gray",
"GradientColor1": [80, 80, 80],
"GradientColor2": [64, 64, 64],
"GradientColor3": [58, 58, 58],
"ShadowColor": [20, 20, 20],
"FontColor" : "white",
"FontColorFaded" : "gray",
"ConnectionPointColor": [169, 169, 169],
"FilledConnectionPointColor": "cyan",
"ErrorColor": "red",
"WarningColor": [128, 128, 0],
"PenWidth": 1.0,
"HoveredPenWidth": 1.5,
"ConnectionPointDiameter": 8.0,
"Opacity": 0.8
},
"ConnectionStyle": {
"ConstructionColor": "gray",
"NormalColor": "darkcyan",
"SelectedColor": [100, 100, 100],
"SelectedHaloColor": "orange",
"HoveredColor": "lightcyan",
"LineWidth": 3.0,
"ConstructionLineWidth": 2.0,
"PointDiameter": 10.0,
"UseDataDefinedColors": false
}
}