概要
ソフトウェアはデータを生成して、データを表示する必要がある。
Qt Quickには、データを表示するためのモデル、ビュー、デリゲートという概念が存在する。
モデル、ビュー、デリゲートは、データの可視化をモジュール化し、開発者がデータの様々な側面をコントロールできる。
また、データにほとんど変更を加えることなく、リストビューとグリッドビューを入れ替えることができる。
同様に、データのインスタンスをデリゲートにカプセル化することで、データの表示方法や処理方法を決定することができる。
- モデル
- データとその構造を含む。
- モデルを作成するためのQMLタイプがいくつかある。
- ビュー
- データを表示するコンテナである。
- ビューは、リストやグリッドでデータを表示する。
- デリゲート
- データがビューにどのように表示されるかを指定する。
- デリゲートはモデルの各データを受け取り、それをカプセル化する。データはデリゲートを通してアクセスできる。
- デリゲートは、データを編集可能なモデルに書き戻すこともできる。(例.
TextField
のonAccepted
ハンドラ内) - データを可視化するには、ビューの
model
プロパティをモデル、delegate
プロパティをコンポーネントやその他の互換性のあるタイプにバインドする。
ビューによるデータの表示
ビューは、アイテムのコレクションのためのコンテナである。
豊富な機能を持ち、スタイルや動作の要求に合わせてカスタマイズすることができる。
Qt Quickの基本セットには、以下に示す標準的なビューが用意されている。
- ListView
- 水平または垂直のリストにアイテムを配置する。
- GridView
- 利用可能なスペース内のグリッドにアイテムを配置する。
- PathView
- アイテムをパス上に配置する。
上記のビューには、それぞれ専用のプロパティと動作がある。
ビューの装飾
ビューでは、header
、footer
、section
等の装飾用プロパティを使用して、見た目をカスタマイズすることができる。
これらのプロパティに対して、オブジェクト(通常は別のビジュアルオブジェクト)をバインドすることにより、ビューを装飾することができる。
footerには、ボーダーを表示するRectangleアイテムや、ビューの上にロゴを表示するヘッダ等がある。
以下の例では、あるクラブがメンバーリストを自社のブランドカラーで装飾している。
メンバーリストはモデルの中にあり、デリゲートはモデルのコンテンツを表示している。
クラブは、ビジュアルアイテムをheader
プロパティとfooter
プロパティにバインドすることにより、メンバーリストを装飾することができる。
ビジュアルアイテムは、同一ファイル、他のファイル、Component
アイテムで定義することができる。
ListModel {
id: nameModel
ListElement { name: "Alice" }
ListElement { name: "Bob" }
ListElement { name: "Jane" }
ListElement { name: "Harry" }
ListElement { name: "Wendy" }
}
Component {
id: nameDelegate
Text {
text: name;
font.pixelSize: 24
}
}
ListView {
anchors.fill: parent
clip: true
model: nameModel
delegate: nameDelegate
header: bannercomponent
footer: Rectangle {
width: parent.width
height: 30;
gradient: clubcolors
}
highlight: Rectangle {
width: parent.width
color: "lightgray"
}
}
Component { // instantiated when header is processed
id: bannercomponent
Rectangle {
id: banner
width: parent.width
height: 50
gradient: clubcolors
border {
color: "#9EDDF2"
width: 2
}
Text {
anchors.centerIn: parent
text: "Club Members"
font.pixelSize: 32
}
}
}
Gradient {
id: clubcolors
GradientStop {
position: 0.0
color: "#8EE2FE"
}
GradientStop {
position: 0.66
color: "#7ED2EE"
}
}
マウスとタッチの操作
ビューは、コンテンツのドラッグやフリックを処理するが、個々のデリゲートとのタッチ操作は処理しない。
デリゲートがタッチ入力に反応してcurrentIndex
プロパティを設定するためには、適切なタッチ処理を持つMouseArea
アイテムをデリゲートに定義する必要がある。
※注意
highlightRangeMode
プロパティがStrictlyEnforceRange
に設定されている場合、ビューは常にcurrentIndex
プロパティが指定されたハイライト範囲内にあることを保証するため、
currentIndex
プロパティはビューをドラッグおよびフリックしても影響を受けない。
ListViewのセクション
ListView
のコンテンツはセクションにグループ化されるため、関連するリストアイテムは、そのセクションに応じてラベル付けされる。
また、セクションは、デリゲートを使用して装飾することもできる。
以下の例では、ListView
に、人名とチームの所属を示すリストを作成している。
ListView
には、隣接するアイテムや関連するアイテムをセクションにまとめることができるproperty
プロパティが存在する。
property
プロパティは、どのリストタイプのプロパティをセクションとして使用するかを決定する。
cliteria
プロパティは、セクション名の表示方法を決定する。
delegate
プロパティは、ListView
等のdelegate
プロパティと同様である。
ListModel {
id: nameModel
ListElement { name: "Alice"; team: "Crypto" }
ListElement { name: "Bob"; team: "Crypto" }
ListElement { name: "Jane"; team: "QA" }
ListElement { name: "Victor"; team: "QA" }
ListElement { name: "Wendy"; team: "Graphics" }
}
Component {
id: nameDelegate
Text {
text: name;
font.pixelSize: 24
anchors.left: parent.left
anchors.leftMargin: 2
}
}
ListView {
anchors.fill: parent
model: nameModel
delegate: nameDelegate
focus: true
highlight: Rectangle {
color: "lightblue"
width: parent.width
}
section {
property: "team"
criteria: ViewSection.FullString
delegate: Rectangle {
color: "#b0dfb0"
width: parent.width
height: childrenRect.height + 4
Text {
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 16
font.bold: true
text: section
}
}
}
}