Qt编程:QNodeEditor中的NodeData类

    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 表示节点端口的数据类型信息,用于类型匹配和显示。

主要功能

  1. 类型标识:通过 ID 唯一标识数据类型

  2. 类型比较:支持等于、不等于和小于比较操作

  3. 类型名称:提供人类可读的类型名称

类成员详解

构造函数

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 是节点间传输的实际数据的基类,需要子类化来实现具体数据类型。

主要功能

  1. 类型检查:提供数据类型一致性检查

  2. 类型信息:返回数据的类型描述

  3. 多态支持:作为数据对象的基类

类成员详解

虚函数

virtual bool sameType(NodeData const &nodeData) const
virtual std::shared_ptr<NodeDataType> type() const = 0
  • sameType(): 检查两个数据对象是否类型相同

  • type(): 纯虚函数,返回数据的类型信息(必须由子类实现)

设计目的

  1. 类型安全:确保只有兼容类型的端口可以连接

  2. 扩展性:通过继承 NodeData 可以支持任意复杂的数据类型

  3. 显示友好:提供人类可读的类型名称用于UI显示

使用场景

  1. 定义新数据类型

    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;
      }
      // ... 具体数据成员和方法
    };
  2. 类型匹配检查

    bool canConnect = (sourceDataType == targetDataType);
  3. 数据传递

    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 的一个具体实现,用于在节点图编辑器中传输整型数据。

  1. 封装整型数据:为节点图编辑器提供整型数据的容器

  2. 类型标识:明确标识这是一个"整数"类型的数据

  3. 数据访问:提供获取数据的多种方式

设计特点

  1. 简单直接:专注于单一数据类型(整数)的封装

  2. 多格式访问:提供原始值和字符串两种访问方式

  3. 类型安全:通过明确的类型标识确保数据连接的正确性

  4. 值语义:存储实际数据而非指针/引用

类成员详解

构造函数

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;  // 存储的实际整数值

使用

  1. 作为节点输出数据

    std::shared_ptr<NodeData> outData = std::make_shared<IntegerData>(42);
  2. 从连接获取输入数据

    auto intData = std::dynamic_pointer_cast<IntegerData>(nodeData);
    if (intData) {
        int value = intData->number();
    }
  3. 在自定义模型中使用

    // 在NodeDataModel子类中
    std::shared_ptr<NodeData> MyModel::outData(PortIndex port) {
        return std::make_shared<IntegerData>(computeValue());
    }

典型关系

  • NodeDataModel 使用 NodeDataType 定义其端口的输入输出类型

  • Connection 使用 NodeDataType 检查连接兼容性

  • 具体数据类继承 NodeData 并实现 type() 方法

重要设计考虑

  1. 类型比较基于ID:只比较类型ID而不是整个对象,便于扩展

  2. 轻量级类型描述NodeDataType 只包含元信息,不包含实际数据

  3. 多态数据容器NodeData 作为基类允许框架处理各种数据类型而无需了解具体细节

这两个类共同构成了 QtNodes 框架类型系统的核心,确保了数据流动的类型安全性和灵活性。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值