NodeDataType 和 NodeData 类,这两个类是 QtNodes 框架中用于处理节点数据类型和数据内容的核心类。
#pragma once
#include "Export.hpp"
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <memory>
namespace QtNodes
{
using NodeDataTypeId = QString;
class NodeDataType
{
public:
NodeDataType() = default;
virtual ~NodeDataType() = default;
NodeDataType(const QString &id, const QString &name) : _id(id), _name(name)
{
}
virtual bool operator==(const NodeDataType &other) const
{
return id() == other.id();
}
virtual bool operator!=(const NodeDataType &other) const
{
return !(*this == other);
}
virtual bool operator<(const NodeDataType &other) const
{
return id() < other.id();
}
NodeDataTypeId id() const
{
return _id;
}
QString name() const
{
return _name;
}
private:
NodeDataTypeId _id;
QString _name;
};
/// Class represents data transferred between nodes.
/// @param type is used for comparing the types
/// The actual data is stored in subtypes
class NODE_EDITOR_PUBLIC NodeData
{
public:
virtual ~NodeData() = default;
virtual bool sameType(NodeData const &nodeData) const
{
return (this->type() == nodeData.type());
}
/// Type for inner use
virtual std::shared_ptr<NodeDataType> type() const = 0;
};
} // namespace QtNodes
NodeDataType 类
NodeDataType
表示节点端口的数据类型信息,用于类型匹配和显示。
主要功能
-
类型标识:通过 ID 唯一标识数据类型
-
类型比较:支持等于、不等于和小于比较操作
-
类型名称:提供人类可读的类型名称
类成员详解
构造函数
NodeDataType() = default; NodeDataType(const QString &id, const QString &name)
-
默认构造函数创建一个空类型
-
带参构造函数指定类型 ID 和名称
操作符重载
virtual bool operator==(const NodeDataType &other) const virtual bool operator!=(const NodeDataType &other) const virtual bool operator<(const NodeDataType &other) const
-
基于类型 ID 进行比较
-
用于类型匹配和排序
访问器方法
NodeDataTypeId id() const QString name() const
-
获取类型 ID 和名称
数据成员
NodeDataTypeId _id; // 类型唯一标识符 QString _name; // 类型显示名称
NodeData 类
NodeData
是节点间传输的实际数据的基类,需要子类化来实现具体数据类型。
主要功能
-
类型检查:提供数据类型一致性检查
-
类型信息:返回数据的类型描述
-
多态支持:作为数据对象的基类
类成员详解
虚函数
virtual bool sameType(NodeData const &nodeData) const virtual std::shared_ptr<NodeDataType> type() const = 0
-
sameType()
: 检查两个数据对象是否类型相同 -
type()
: 纯虚函数,返回数据的类型信息(必须由子类实现)
设计目的
-
类型安全:确保只有兼容类型的端口可以连接
-
扩展性:通过继承
NodeData
可以支持任意复杂的数据类型 -
显示友好:提供人类可读的类型名称用于UI显示
使用场景
-
定义新数据类型:
class MyData : public NodeData { public: std::shared_ptr<NodeDataType> type() const override { static auto type = std::make_shared<NodeDataType>("my_data", "My Data"); return type; } // ... 具体数据成员和方法 };
-
类型匹配检查:
bool canConnect = (sourceDataType == targetDataType);
-
数据传递:
std::shared_ptr<NodeData> data = std::make_shared<MyData>(...);
自定义IntegerData
类
#pragma once
#include <nodes/NodeDataModel>
using QtNodes::NodeData;
using QtNodes::NodeDataType;
/// The class can potentially incapsulate any user data which
/// need to be transferred within the Node Editor graph
class IntegerData : public NodeData
{
public:
IntegerData() : _number(0.0)
{
}
IntegerData(int const number) : _number(number)
{
}
std::shared_ptr<NodeDataType> type() const override
{
return std::make_shared<NodeDataType>("integer", "Integer");
}
int number() const
{
return _number;
}
QString numberAsText() const
{
return QString::number(_number);
}
private:
int _number;
};
IntegerData
是 NodeData
的一个具体实现,用于在节点图编辑器中传输整型数据。
-
封装整型数据:为节点图编辑器提供整型数据的容器
-
类型标识:明确标识这是一个"整数"类型的数据
-
数据访问:提供获取数据的多种方式
设计特点
-
简单直接:专注于单一数据类型(整数)的封装
-
多格式访问:提供原始值和字符串两种访问方式
-
类型安全:通过明确的类型标识确保数据连接的正确性
-
值语义:存储实际数据而非指针/引用
类成员详解
构造函数
IntegerData() : _number(0.0) {} // 默认构造,初始化为0 IntegerData(int const number) : _number(number) {} // 用指定整数初始化
核心方法
type()
std::shared_ptr<NodeDataType> type() const override { return std::make_shared<NodeDataType>("integer", "Integer"); }
-
实现
NodeData
的纯虚函数 -
返回描述此数据类型的
NodeDataType
对象 -
类型ID为"integer",显示名称为"Integer"
数据访问方法
int number() const { return _number; } // 获取原始int值 QString numberAsText() const { return QString::number(_number); } // 获取字符串形式
数据成员
int _number; // 存储的实际整数值
使用
-
作为节点输出数据:
std::shared_ptr<NodeData> outData = std::make_shared<IntegerData>(42);
-
从连接获取输入数据:
auto intData = std::dynamic_pointer_cast<IntegerData>(nodeData); if (intData) { int value = intData->number(); }
-
在自定义模型中使用:
// 在NodeDataModel子类中 std::shared_ptr<NodeData> MyModel::outData(PortIndex port) { return std::make_shared<IntegerData>(computeValue()); }
典型关系
-
NodeDataModel
使用NodeDataType
定义其端口的输入输出类型 -
Connection
使用NodeDataType
检查连接兼容性 -
具体数据类继承
NodeData
并实现type()
方法
重要设计考虑
-
类型比较基于ID:只比较类型ID而不是整个对象,便于扩展
-
轻量级类型描述:
NodeDataType
只包含元信息,不包含实际数据 -
多态数据容器:
NodeData
作为基类允许框架处理各种数据类型而无需了解具体细节
这两个类共同构成了 QtNodes 框架类型系统的核心,确保了数据流动的类型安全性和灵活性。