我有一个分层数据结构,可以在几个Qt视图(或小部件)中显示。数据层次结构由异构元素类型组成,如:
House
|- Floor
| |- Room
| | |- Window
| | |- ...
| |- Room
| | |- ...
|- ...
所有元素(House,Floor,Room,...)都有可以显示的属性。请注意,这是一个简化的示例。层次结构由各种视图绘制。例如。只是模板列表中房间的标识符(QListView / Widget),自定义视图(每个元素的QWidget子类的层次结构),编辑例如属性的详细视图。一个楼层(QWidget子类或QWizard)。
也可以在多个实例之间拖放元素。例如。移动房间到不同的楼层。可以将特定楼层声明为模板,并从例如模板列表中拖出楼层。自定义视图(组成房屋的地方)。
Qt使用Model/View architecture分隔数据,模型和视图。因为我有完全不同类型的视图,我假设每个视图都需要相应的模型。对于我的自定义层次结构视图,每个元素都有自己的可视化,因此层次结构存在(但不应该存在)三次:数据层次结构,模型层次结构和视图层次结构。这变得非常混乱,因为如果拖放,删除或复制元素,则必须更新每个层次结构。更好的方法是Presentation-Abstraction-Control模式。但是,PAC不适用,因为必须设置QWidget的父级,才能将子级嵌入父视图中。因此,QWidget无法引用负责对层次结构建模的代理。
在我看来,Qt非常善于表示同类数据类型(如字符串)的列表,表和树。在我的例子中,每个元素都有一组独立的属性,不能简单地以表格的形式表达。在这discussion中,不鼓励将方形钉子放入圆孔中。意思是,不要强制表格表示任何设计。
我的问题的核心是在一个设计概念中统一以下特征:具有不同细节水平的分层数据的可视化。支持视图之间的拖放,复制数据并生成适当的模型/视图组件。支持视图中的拖放,这会影响数据,模型和视图层次结构(我希望避免实现三次)。由于地板和房间太复杂,我无法为所有子组件提供一个房屋模型。我发现管理三个(或更多)层次结构进行拖放,删除或复制操作非常笨拙。
我的问题有最佳实践,设计模式或不同的方法吗?这个问题可以用Qt解决吗?
我很感激每一个建议。
答案 0 :(得分:0)
我的层次结构有一段时间我有类似的问题。 Qt的模型 - 视图 - 委托架构中的所有内容都取决于您如何组织数据以及您愿意获得的复杂程度。对于非常简单的应用程序,从基于项目的方法实现事物,在视图级别编辑项目显示是有意义的。这非常麻烦。
听起来你很愿意变得非常复杂,所以我建议采用基于模型的方法。您可以控制模型级别的几乎所有内容,包括一些基本的显示元素,数据组织和(最重要的)heirarchies。
当我开始让我的对象继承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()以返回计算值,存储值等等。自定义模型允许您将每个项目视为对象,而不是表格/列表中的单个单元格。
标准视图应该为您提供一般所需的大部分内容。使用委托自定义某些数据类型(楼层,Windows,整数,字符串等)的显示。希望这是有道理的。