3

複数の Qt ビュー (またはウィジェット) で視覚化される階層データ構造があります。データ階層は、次のような異種の要素タイプで構成されています。

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

すべての要素 (家、床、部屋など) には、表示可能な属性があります。これは単純化された例であることに注意してください。階層は、さまざまなビューによって描画されます。たとえば、テンプレート (QListView/Widget) のリスト内の部屋の識別子、カスタム ビュー (各要素の QWidget サブクラスの階層)、フロア (QWidget サブクラスまたは QWizard) などのプロパティを編集するための詳細ビュー。

複数のインスタンス間で要素をドラッグ アンド ドロップすることもできます。たとえば、部屋を別のフロアに移動します。特定のフロアをテンプレートとして宣言し、カスタム ビュー (家が構成されている場所) などのテンプレート リストからフロアをドラッグすることができます。

Qt はモデル/ビュー アーキテクチャを使用して、データ、モデル、およびビューを分離します。私はまったく異なるタイプのビューを持っているため、各ビューに対応するモデルが必要であると想定しています。カスタム階層ビューの場合、各要素には独自の視覚化があるため、階層は 3 回存在します (ただし、存在すべきではありません): データ階層、モデル階層、およびビュー階層です。要素がドラッグ アンド ドロップ、削除、またはコピーされると、すべての階層を更新する必要があるため、これは非常に面倒です。より良いアプローチは、Presentation-Abstraction-Controlです。パターン。ただし、親ビューに子を埋め込むには、QWidget の親を設定する必要があるため、PAC は適用できません。したがって、QWidget は、階層のモデリングを担当するエージェントを参照できません。

Qt は、同種のデータ型 (文字列など) のリスト、テーブル、およびツリーを表現するのに非常に優れているように思えます。私の場合、すべての要素には、単純にテーブルの形で表現できない属性の個別のセットがあります。この議論では、四角いペグを無理に丸い穴に押し込むことはお勧めできません。つまり、テーブル表現にデザインを強制しないことです。

私の問題の核心は、次の機能を 1 つの設計概念に統合することです。 さまざまなレベルの詳細を持つ階層データの視覚化。データをコピーし、適切なモデル/ビュー コンポーネントを生成する、ビュー間のドラッグ アンド ドロップをサポートします。データ、モデル、およびビュー階層に影響を与えるビューでのドラッグ アンド ドロップのサポート (これを 3 回実装することは避けたいと思います)。床と部屋が複雑すぎるため、すべてのサブコンポーネントを備えた家のモデルを 1 つ提供することはできません。1 回のドラッグ アンド ドロップ、削除、またはコピー操作で 3 つ (またはそれ以上) の階層を管理するのは面倒です。

ベスト プラクティス、デザイン パターン、または問題に対する別のアプローチはありますか? この問題は Qt で解決できますか?

私はすべての提案に感謝しています。

4

1 に答える 1

0

階層構造でしばらくの間、同様の問題がありました。Qt のモデル - ビュー - デリゲート アーキテクチャのすべては、データをどのように整理し、どれだけ複雑にするかによって決まります。非常に単純なアプリケーションの場合、ビュー レベルでアイテム表示を編集する、アイテム ベースのアプローチから物事を実装することは理にかなっています。これは非常に面倒です。

あなたはかなり複雑になることを望んでいるように聞こえるので、モデルベースのアプローチを取ることをお勧めします。一部の基本的な表示要素、データ編成、および (最も重要な) 階層を含む、モデル レベルでほぼすべてを制御できます。

オブジェクトが 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()をカスタマイズして、計算された値、格納された値などを返すことができます。モデルをカスタマイズすると、各アイテムをテーブル/リスト内の単一のセルではなく、オブジェクトとして考えることができます。

標準ビューは、一般的に必要なもののほとんどを提供するはずです。デリゲートを使用して、特定のデータ型 (フロア、ウィンドウ、整数、文字列など) の表示をカスタマイズします。それが理にかなっていることを願っています。

于 2013-04-16T16:28:55.380 に答える