2

我有一個分層數據結構,可以在幾個Qt視圖(或小部件)中可視化。數據層次結構由異質元素類型,如:在異構數據層次結構的不同視圖之間拖放

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

所有元素(樓,樓層,房間,...)有一個可以顯示的屬性。請注意,這是一個簡化的例子。層次結構由各種視圖繪製。例如。只是模板列表(QListView/Widget)中的房間標識符,自定義視圖(每個元素的QWidget子類層次結構),編輯屬性的詳細視圖等。一個地板(QWidget子類或QWizard)。

也可以在幾個實例之間拖放元素。例如。將房間移動到不同的樓層。可以將特定樓層聲明爲模板,並且可以從例如模板列表中拖拽樓層。自定義視圖(組成房屋的地方)。

Qt使用Model/View architecture來分隔數據,模型和視圖。因爲我有完全不同類型的視圖,所以我假設每個視圖都需要相應的模型。在我的自定義層次視圖的情況下,每個元素都有自己的可視化,因此層次結構存在(但不應該存在)三次:數據層次結構,模型層次結構和視圖層次結構。這變得非常混亂,因爲每個層次結構都必須更新,如果一個元素被拖放,刪除或複製。更好的方法是Presentation-Abstraction-Control模式。但是,PAC不適用,因爲必須設置QWidget的父項,以便將子項嵌入其父視圖中。因此,QWidget無法引用負責建立層次結構的代理。

在我看來,Qt在代表同類數據類型(如字符串)的列表,表和樹方面非常出色。就我而言,每個元素都有一組獨立的屬性,不能簡單地以表格的形式表示。在這個discussion不鼓勵強迫一個正方形釘入一個圓孔。意思是,不要以表格形式強制任何設計。

我的問題的核心是在一個設計概念中統一下列功能:用不同層次的細節對分層數據進行可視化。支持視圖之間的拖放操作,從而複製數據並生成適當的模型/視圖組件。在視圖中支持拖放,這會影響數據,模型和視圖層次結構(我希望避免實施三次)。由於樓層和房間太複雜,我無法爲其所有子組件提供一個房屋模型。我發現爲一個拖放,刪除或複製操作管理三個(或更多)層次結構是很笨拙的。

是否有最佳做法,設計模式或對我的問題採取不同的方法?這個問題是否可以用Qt解決?

我很感謝每一個建議。

回答

0

我有一段時間與我的分層結構類似的問題。 Qt的model-view-delegate體系結構中的所有內容取決於你如何組織數據以及你願意獲得多少複雜性。對於非常簡單的應用程序,從基於項目的方法實現東西是有意義的,在視圖級別編輯項目顯示。這非常快速地變得非常混亂。

聽起來像你願意變得相當複雜,所以我建議採取基於模型的方法。您可以控制模型級別的幾乎所有內容,包括一些基本的顯示元素,數據組織和(最重要的)後裔。

我發現它有助於在入門有我的對象繼承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()返回一個計算值,儲值,等等。定製模型允許您將每個項目視爲對象,而不是表格/列表中的單個單元格。

標準視圖應該給你大部分你需要的一般基礎。使用委託自定義某些數據類型(Floors,Windows,整數,字符串等)的顯示。希望這是有道理的。

+0

我錯過了與QObject不同的QStandardItem可以克隆的事實。利用UserRole似乎也是「數量」。我必須考慮你的建議,但現在看來,我正在尋找。我會回到你身邊。 – Marian