05-1_Qt 5.9 C++ 開発ガイド_モデル/ビュー構造の基本 (基本原則、データ モデル、コンポーネントの試行、プロキシ)

Model/View(模型/视图) 结构是 Qt 中用界面组件显示与编辑数据的一种结构,视图 (View)是显示和编辑数据的界面组件,模型 (Model) 是视图与原始数据之间的接口。モデル/ビュー構造の一般的な用途はデータベース アプリケーションです。たとえば、データベース内のデータ テーブルを OTableView コンポーネントで表示および編集できます。
主なビューコンポーネントは QListView、QTreeView、QTableView で、第 4 章で紹介した QListWidget、QTreeWidget、QTableWidget はそれぞれこれら 3 つのクラスに属し、データモデルを使用せず、コンポーネントの各項目にデータを直接格納します便利类

この章では、QListView、QTreeView、QTableView ビュー コンポーネントを含むモデル/ビュー構造の原則と、QStringListModel や OStandardItemModel などのモデル クラスの使用法を紹介します。

Qt でのモデル/ビューの導入と使用 (モデル/ビュー プログラミング) は、次のような利点があるフレームワーク モードです。

  • より大きなデータセットを処理する場合、各コンポーネントはパフォーマンスを低下させることなく独自の役割を果たします。
  • モデルは複数のビューにマッピングできるため、同じデータをさまざまな方法で表示できます。
  • 基礎となるデータ ソースのストレージが変更された場合、モデルに対処するだけで済みます。

1 モデル/ビューの基本原則

GUI アプリケーションの非常に重要な機能は、ユーザーがインターフェイス上でデータ (通常はデータベース アプリケーションなど) を編集および変更できることです。数据库应用程序中,用户在界面上执行各种操作,实际上是修改了界面组件所关联的数据库内的数据。

編集されたデータからインターフェイス コンポーネントを分離し、データ ソースを介してそれらを接続することは、インターフェイスとデータを扱うより良い方法です。Qt はモデル/ビュー構造を使用してこの関係を処理します。モデル/ビューの基本構造を次の図に示します。各部の機能は以下の通りです。

ここに画像の説明を挿入

  • データ (Data) は、データベース内のデータ テーブルや SQL クエリ結果、メモリ内の StringList、ディスク ファイル構造などの実際のデータです。
  • ビューまたはビューコンポーネント(View)は、画面上のインターフェースコンポーネントであり、データモデルから各データ項目のモデルインデックス(モデルインデックス)を取得し、モデルインデックスを通じてデータを取得し、インターフェースコンポーネントに提供します(表示のみの場合はプロキシは必要ありません) 显示数据Qt は、QListView、QTreeView、QTableView などの既製のデータ ビュー コンポーネントをいくつか提供します。
  • モデルまたはデータ モデル (モデル) は実際のデータと通信し、ビュー コンポーネントにデータ インターフェイスを提供します。ビュー コンポーネントによる表示と編集のために生データから必要なコンテンツを抽出します。Qt には事前定義されたデータ モデルがいくつかあります。たとえば、QStringListModel は StringList のデータ モデルとして使用でき、QSglTableModel はデータベース内のデータ テーブルのデータ モデルとして使用できます。

データ ソースと表示インターフェイスはモデル/ビュー構造によって分離されているため、データ モデルを異なるビューで表示でき、データ モデルを変更せずに特別なビュー コンポーネントを設計できます。

  • Model/View 構造では、Delegate 関数も提供されています。Delegate 関数を使用すると、ユーザーはデータ インターフェイスをカスタマイズできます (表示および編集が必要な場合はプロキシが必要です)。標準のビュー コンポーネントでは、Delegate 関数はデータを表示します。データが編集されると、Delegate はモデル インデックスを通じてデータ モデルと通信し、データ編集用のエディタ (通常は QLineEdit コンポーネント) を提供します显示和编辑方式。

モデル、ビュー、およびデリゲートは、シグナルとスロットを使用して通信します。ソースデータが変更されると、データモデルは信号を発してビューコンポーネントに通知し、ユーザーがインターフェース上でデータを操作すると、ビューコンポーネントは操作情報を表す信号を発し、データを編集する場合、エージェントは信号を発してデータモデルとビューコンポーネントエディタに状態を通知します。

2 データモデル

項目データに基づくすべてのデータ モデル (モデル) は、ビュー コンポーネントとエージェントがデータにアクセスするためのインターフェイスを定義する QAbstractItemModel クラスに基づいています。データはデータ モデルに保存する必要はなく、他のクラス、ファイル、データベース、または任意のデータ ソースにすることができます。Qt のデータ モデルに関連するいくつかの主要クラスの階層構造を次の図に示します。

ここに画像の説明を挿入

図内の抽象クラスは直接使用できず、一部の純粋仮想関数を実装するにはサブクラスによって継承される必要があります。Qt は項目データ処理用にいくつかのモデル クラスを提供します。一般的なものを以下の表に示します。

ここに画像の説明を挿入

データベースの 3 つのモデルについては後で紹介します。既存のモデル クラスが要件を満たさない場合は、QAbstractItemModel、QAbstractListModel、または QAbstractTableModel から継承して、独自のカスタマイズされたデータ モデル クラスを生成できます。

3 ビューコンポーネント

ビューコンポーネント(View)はデータモデルのデータを表示するインターフェースコンポーネントであり、Qtが提供するビューコンポーネントは以下のとおりです。

  • QListView: 1 列のリスト データを表示するために使用され、1 次元のデータ操作に適しています。
  • QTreeView: ツリー構造データの表示に使用され、ツリー構造データの操作に適しています。
  • QTableView: 表形式のデータを表示するために使用され、2 次元の表形式データの操作に適しています。
  • QColumnView: 複数の QListView を使用してツリー階層を表示し、ツリー構造の 1 つのレイヤーが OListView で表示されます。
  • QHeaderView: QTableView の行ヘッダーや列ヘッダーなど、行ヘッダーまたは列ヘッダーを提供するビュー コンポーネント。

ビューコンポーネントがデータを表示するとき、只需调用视图类的 setModel()函数,为视图组件设置一个数据模型就可以实现视图组件与数据模型之间的关联,在视图组件上的修改将自动保存到关联的数据模型里,一个数据模型可以同时在多个视图组件里显示数据。

データ編集に使用できる以前の QListWidget、QTreeWidget、QtableWidget 3 コンポーネントが導入されました。これら 3 つのクラスはコンビニエンス クラスと呼ばれ、それぞれ 3 つのビュー クラスのサブクラスであり、その階層関係は次の図に示されています。

ここに画像の説明を挿入

Model/View 構造のいくつかのビュー クラスは QAbstractItemView から直接継承しますが、コンビニエンス クラスは対応するビュー クラスから継承します。

ビューコンポーネントクラスのデータは別のデータモデルを採用しており、ビューコンポーネントはデータを格納しません。コンビニエンス クラスは、コンポーネントのノードまたはセルごとに項目を作成し、その項目を使用してデータや書式設定などを保存します。したがって、コンビニエンス クラスにはデータ モデルはなく、実際にはデータ モデルの機能を項目の形式で統合し、インターフェイスをデータにバインドします。したがって、コンビニエンス クラスには大規模なデータ ソースを柔軟に処理する機能がなく、小規模なデータの表示と編集に適しています。

エージェント4名

エージェント (Delegate) は、ビュー コンポーネント上のデータを編集するためのエディタを提供します。たとえば、テーブル コンポーネント内のセルのデータを編集する場合、デフォルトでは QLineEdit エディット ボックスが使用されます。エージェントは、データ モデルから対応するデータを取得し、それをエディターに表示し、データを変更した後にデータ モデルに保存する責任があります。
QAbstractItemDelegate はすべてのプロキシ クラスの基本クラスであり、抽象クラスとして直接使用することはできません。そのサブクラスの 1 つである QStyledItemDelegate は、Qt のビュー コンポーネントによってデフォルトで使用されるプロキシ クラスです。

整数の入力のみを許可するなど、一部の特殊なデータ編集要件の場合は、QSpinBox をプロキシ コンポーネントとして使用する方が適切であり、リストからデータを選択する場合は QComhoBox をプロキシ コンポーネントとして使用する方が適切です。現時点では、QStyledItemDelegate から継承してカスタム プロキシ クラスを作成できます。

5 モデル/ビュー構造のいくつかの概念

5.1 モデル/ビューの基本構造

モデル/ビュー構造では、データ モデルは、ビュー コンポーネントとエージェントがデータにアクセスするための標準インターフェイスを提供します。Qt では、すべてのデータ モデル クラスは QAbstractItemModel から継承されます。基になるデータ構造がデータをどのように編成するかに関係なく、QAbstractItemModel のサブクラスはテーブル階層内のデータを表します。ビュー コンポーネントはこのルールを使用してモデル内のデータにアクセスしますが、ユーザーに表示されるフォームは異なります。
以下の図は、データ モデルの 3 つの一般的な表現を示しています。不管数据模型的表现形式是怎么样的,数据模型中存储数据的基本单元都是项(item),每个项有一个行号、一个列号,还有一个父项(parent item)。在列表和表格模式下,所有的项都有一个相同的顶层项 (root item): 在树状结构中,行号、列号、父项稍微复杂一点,但是由这 3 个参数完全可以定义一个项的位置,从而存取项的数据。

ここに画像の説明を挿入

5.2 モデルインデックス

データ表現がデータ アクセス方法から確実に分離されるようにするために、モデル インデックスの概念がデータ モデルに導入されます。データ モデルを通じてアクセスされる各データにはモデル インデックスがあり、ビュー コンポーネントとプロキシの両方がモデル インデックスを使用してデータを取得します。
OModelIndex モデルのインデックスを表すクラス。モデル インデックスは、データ アクセスへの一時的なポインタを提供し、データ モデルを通じてデータを抽出または変更するために使用されます。モデル内で編成されたデータの構造はいつでも変更される可能性があるため、モデル インデックスは一時的です。永続モデル インデックスを使用する必要がある場合は、OPersistentModelIndex クラスを使用します。

5.3 行番号と列番号

データ モデルの基本的な形式は行と列で定義された表形式のデータですが、これは基になるデータが 2 次元配列に格納されることを意味するものではなく、行と列の使用はコンポーネント間の相互作用の便宜のための単なる規定です。データには、モデル インデックスの行番号と列番号を通じてアクセスできます。

モデル インデックスを取得するには、行番号、列番号、親のモデル インデックスの 3 つのパラメータを指定する必要があります。たとえば、上図のテーブル モデルの 3 つのデータ項目 A、B、C の場合、それらのモデル インデックスを取得するコードは次のとおりです。

QModelIndex indexA = model->index(00QModelIndex());
QModelIndex indexB = model->index(11QModelIndex());
OModelIndex indexC = model->index(21QModelIndex());

モデル インデックスを作成する関数では、行番号、列番号、および親のモデル インデックスを渡す必要があります。リストおよびテーブル モードのデータ モデルの場合、最上位ノードは常に QModelIndex() によって表されます。

5.4 保護者

データ モデルがリストまたはテーブルの場合、行番号と列番号を使用してデータを格納する方が直感的です。すべてのデータ項目の親項目は最上位の項目です。データ モデルがツリー構造の場合、状況はより複雑になります (ツリー構造では、項目は通常ノードと呼ばれます)。ノードは親ノードを持つことも、他のノードの親ノードになることもできます。データ項目のモデル インデックスを構築するときは、正しい行番号、列番号、および親ノードを指定する必要があります。

上記のツリー モデルでは、ノード A とノード C の親ノードがトップレベル ノードであり、モデル インデックスを取得するコードは次のとおりです。

QModelIndex indexA = model->index(00OModelIndex());
OModelIndex indexC = model->index(21QModelIndex());

ただし、ノード B の親ノードはノード A であり、ノード B のモデル インデックスは次のコードによって生成されます。

QModelIndex indexB = model->index(10,indexA);

5.5 役割

データモデルの項目にデータを設定する際に、異なる項目の役割(項目ロール)のデータを与えることができます。たとえば、データ モデル クラス QStandardItemModel の項目データ クラスは QStandardItem で、データを設定するためのその関数は次のとおりです。

void QStandardItem::setData(const QVariant &value,int role= Qt::UserRole + 1)

このうち、value は設定する必要があるデータ、role はデータを設定する役割です。アイテムには、さまざまな機会に応じて、さまざまな役割のデータを含めることができます。

role は複数の値を持つ Qt:ItemDataRole の列挙型で、たとえば、Qt:DisplayRole はビューコンポーネントに表示される文字列、Qt:ToolTipRole はマウスチップメッセージ、Qt.:UserRole はデータをカスタマイズできます。項目の標準ロールは Ot::DisplayRole です。

また、異なる役割のデータを取得するには、項目のデータを取得する際に役割を指定する必要があります。

QVariant QStandardItem::data(int role = Qt::UserRole + 1) const

アイテムのさまざまな役割のデータを定義すると、ビュー コンポーネントとデリゲート コンポーネントにデータの表示方法が指示されます。たとえば、次の図では、項目の DisplayRole データは表示される文字列、DecorationRole は表示を装飾するために使用される属性、TolTipRole はマウス チップ情報を定義します。ビューコンポーネントが異なれば、さまざまな役割データの解釈と表示が異なる場合があり、特定の役割データを無視する場合もあります。

ここに画像の説明を挿入

コンビニエンス クラス QListWidget、QTreeWidget、および QTableWidget の使用については以前に紹介しました。次の記事では、Qt の事前定義された QstringListModel、OFileSystemModel、OStandardItemModel およびビュー コンポーネント QListView、QTableView、および QTreeView の使用を含む、Model/View 構造の基本的な使用法を紹介します。また、カスタム エージェントの設計および使用方法も紹介します。データベースに関係するモード/ビューの使用法については、データベースの章で別途紹介します。

6. より良いモデル/ビューの紹介ビデオ: Qt 16: モデル/ビューの紹介と使用法 (モデル/ビュー プログラミング) ; Qt 17: モデル/ビュー プログラミングの例 (モデル/ビュー プログラミング) (未視聴) ; Qt 18: モデル ビュー プログラミングの例 (未視聴)ビデオ ブロガーのブログ アドレス

おすすめ

転載: blog.csdn.net/Dasis/article/details/131796129