qt - 在异构数据层次结构的不同 View 之间拖放

标签 qt design-patterns model-view-controller user-interface hierarchy

我有一个分层数据结构,要在多个 Qt View (或小部件)中可视化。数据层次结构由异构元素类型组成,例如:

House
 |- Floor
 |   |- Room
 |   |   |- Window
 |   |   |- ...
 |   |- Room
 |   |   |- ...
 |- ...

所有元素(房子、楼层、房间……)都有可以显示的属性。请注意,这是一个简化的示例。层次结构由各种 View 绘制。例如。只是模板列表中房间的标识符(QListView/Widget),自定义 View (每个元素的 QWidget 子类的层次结构),用于编辑属性的详细 View ,例如一层(QWidget 子类或 QWizard)。

也可以在多个实例之间拖放元素。例如。将房间移动到不同的楼层。可以将特定楼层声明为模板并从模板列表中拖动楼层,例如自定义 View (房屋组成的地方)。

Qt 使用 Model/View architecture分离数据、模型和 View 。因为我有完全不同类型的 View ,所以我假设每个 View 都需要一个相应的模型。在我的自定义层次结构 View 中,每个元素都有自己的可视化,因此层次结构存在(但不应该存在)三次:数据层次结构、模型层次结构和 View 层次结构。这变得非常困惑,因为如果拖放、删除或复制元素,则必须更新每个层次结构。更好的方法是 Presentation-Abstraction-Control图案。但是,PAC 不适用,因为必须设置 QWidget 的父级,才能将子级嵌入到它们的父级 View 中。因此,QWidget 不能引用负责建模层次结构的代理。

在我看来,Qt 非常擅长表示同类数据类型(如字符串)的列表、表格和树。在我的例子中,每个元素都有一组单独的属性,不能简单地以表格的形式表示。在这个discussion不鼓励将方钉强行插入圆孔。意思是,不要在表表示中强制进行任何设计。

我的问题的核心是将以下特征统一在一个设计概念中:具有不同详细程度的分层数据的可视化。支持 View 之间的拖放,复制数据并生成适当的模型/ View 组件。支持在 View 中拖放,这会影响数据、模型和 View 层次结构(我想避免实现三次)。我无法为包含所有子组件的房屋提供一个模型,因为地板和房间太复杂了。我发现为一个拖放、删除或复制操作管理三个(或更多)层次结构很笨拙。

对于我的问题,是否有最佳实践、设计模式或不同的方法?这个问题可以用 Qt 解决吗?

我感谢每一个建议。

最佳答案

一段时间以来,我的层次结构也遇到过类似的问题。 Qt 的模型- View -委托(delegate)架构中的一切都取决于您如何组织数据以及您愿意将其复杂化。对于非常简单的应用程序,从基于项目的方法实现事物是有意义的,在 View 级别编辑项目显示。这很快就会变得非常困惑。

听起来您愿意变得非常复杂,所以我建议您采用基于模型的方法。您几乎可以在模型级别控制所有内容,包括一些基本的显示元素、数据组织和(最重要的)层次结构。

我发现它在开始让我的对象继承时很有帮助 QStandardItem和子类化 QStandardItemModel ,因为 QStandardItem 已经为我设置了父子层次结构和索引。我喜欢递增 Qt::UserRole 并为我的每个自定义数据类型分配一个 enum 值。例如:

enum FloorProperties
{
    DAT_CARPETING = Qt::UserRole +100,
    DAT_AREA = Qt::UserRole +101,
    DAT_FLOORNUM = Qt::UserRole +102
}

即使您不想将存储值与每个数据角色相关联(使用方便的 QStandardItem::setData() ),您也可以自定义 QStandardItemModel::data()返回计算值、存储值等。自定义模型让您可以将每个项目视为一个对象,而不是表格/列表中的单个单元格。

标准 View 应该可以为您提供一般情况下所需的大部分内容。使用委托(delegate)为某些数据类型(Floors、Windows、整数、字符串等)自定义显示。希望这是有道理的。

关于qt - 在异构数据层次结构的不同 View 之间拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16035969/

相关文章:

c# - 用 C# 创建像扫雷这样的模式的问题

design-patterns - 工厂采用静态方法实现

node.js - NodeJs sails 模型替换现有表

c++ - 使用 QT + OpenCV 的多线程

c++ - 设计 QFrame 和 QSizeGrip

javascript - 如何通过Qt模拟按键事件并在QML的JavaScript中使用它?

java - 将类型推广到 Java 中的类型系统

c# - MVC 网络应用程序 WIX 安装程序

javascript - Node JS - MVC - 命名约定

c++ - Qt Creator 自动补全