C
Qt Quick Ultraliteにおけるモデルとビュー
アプリケーションでは、データの提供や表示が必要になることがよくあります。Qt Quick では、データを表示するために「モデル」、「ビュー」、「デリゲート」という概念が用いられています。これらはデータの可視化をモジュール化することで、開発者やデザイナーがデータのさまざまな側面を制御できるようにします。 開発者は、データにほとんど変更を加えることなく、リストビューをグリッドビューに置き換えることができます。同様に、データのインスタンスをデリゲートにカプセル化することで、開発者はデータの表示方法や処理方法を指定できるようになります。

- モデル- データとその構造を保持します。モデルを作成する方法はいくつかあります。
- ビュー- データを表示するコンテナです。ビューは、データをリストやグリッドの形式で表示します。
- デリゲート- データがビューにどのように表示されるかを決定します。デリゲートはモデル内の各データを取得してカプセル化します。データへのアクセスはデリゲートを介して行われます。また、デリゲートは編集可能なモデルにデータを書き戻すこともできます。
データを可視化するには、ビューのmodel プロパティをモデルにバインドし、delegate プロパティをコンポーネントまたはその他の互換性のある型にバインドします。
ビューによるデータの表示
ビューは、項目のコレクションを格納するコンテナです。機能豊富で、スタイルや動作の要件に合わせてカスタマイズすることができます。
Qt Quick の基本的なグラフィカルタイプには、一連の標準ビューが用意されています:
これらのタイプには、それぞれ固有のプロパティや動作があります。詳細については、各タイプのドキュメントを参照してください。
ビューデリゲート
ビューは、リスト内の項目を視覚的に表現するためにデリゲートを必要とします。ビューは、デリゲートによって定義されたテンプレートに従って、各リスト項目を可視化します。モデル内の項目には、index プロパティおよび項目のプロパティを通じてアクセスできます。
Component { id: petdelegate Text { id: label width: view.width / petlist.count height: view.height / petlist.count font.pixelSize: 24 text: if (index == 0) label.text = model.type + " (default)" else text: model.type } }

モデル
データは、名前付きデータロールを通じてデリゲートに提供され、デリゲートはこれらにバインドすることができます。以下は、typeとageという2つのロールを持つListModel と、これらのロールにバインドしてその値を表示するデリゲートを持つListView の例です。
import QtQuick 2.15 Rectangle { color: "white" ListModel { id: myModel ListElement { type: "Dog" age: 8 } ListElement { type: "Cat" age: 5 } } Component { id: myDelegate Text { width: listView.width / myModel.count height: listView.height / myModel.count text: model.type + ", " + model.age } } ListView { id: listView anchors.fill: parent model: myModel delegate: myDelegate } }
どのロールにアクセスできるかを制御し、デリゲートをより自己完結型にしてビューの外でも利用できるようにするには、必須プロパティを使用できます。 デリゲートに必須プロパティが含まれている場合、名前付きロールは提供されません。その代わりに、Qt Quick Ultraliteエンジンは、必須プロパティの名前がモデルのロール名と一致するかどうかを確認します。一致する場合、そのプロパティはモデルからの対応する値にバインドされます。
import QtQuick 2.15 Rectangle { color: "white" ListModel { id: myModel ListElement { type: "Dog" age: 8 noise: "meow" } ListElement { type: "Cat" age: 5 noise: "woof" } } Component { id: delegate Text { width: listView.width / myModel.count height: listView.height / myModel.count required property string type required property int age text: type + ", " + age // WRONG: text: type + ", " + noise // The above line would cause a compiler error // as there is no required property noise } } ListView { id: listView anchors.fill: parent model: myModel delegate: delegate } }
モデルのプロパティとデリゲートのプロパティの間で命名上の競合がある場合、代わりに修飾されたモデル名を使用してロールにアクセスできます。 たとえば、Text 型にtypeプロパティとageプロパティがある場合、上記の例では、モデルからのtypeおよびageの値ではなく、これらのプロパティの値が表示されます。この場合、デリゲートがモデルからのプロパティ値を確実に表示するようにするには、model.type およびmodel.age のようにプロパティを参照すればよかったことになります。
また、デリゲートでは、モデル内の項目のインデックスを含む特別なインデックスロールも利用可能です。なお、項目がモデルから削除された場合、このインデックスは -1 に設定されることに注意してください。 インデックスロールにバインドする場合は、インデックスが -1 になる可能性、つまりその項目がもはや有効ではない可能性をロジックで考慮するようにしてください。通常、その項目はまもなく破棄されますが、一部のビューではデリゲートの破棄を遅延させることも可能です。
名前付きロールを持たないモデルでは、データはmodelDataロールを介して提供されます。modelDataロールは、ロールが 1 つしかないモデルにも提供されます。この場合、modelDataロールには、名前付きロールと同じデータが含まれます。
注: デリゲートに必須プロパティが含まれている場合、index およびmodelDataロールにはアクセスできません。ただし、デリゲート側に同じ名前の必須プロパティが存在する場合はこの限りではありません。
リストモデル
ListModel は、QMLで指定された型の単純な階層構造です。利用可能なロールは、ListElement プロパティによって指定されます。
ListModel { id: fruitModel ListElement { name: "Apple" cost: 245 } ListElement { name: "Orange" cost: 325 } ListElement { name: "Banana" cost: 195 } }
上記のモデルには、nameとcost の 2 つのロールがあります。これらは、ListView デリゲートによってバインドすることができます。例えば、次のようにします。
ListView { anchors.fill: parent model: fruitModel delegate: Row { width: parent.width / fruitModel.count height: parent.height / fruitModel.count Text { text: "Fruit: " + model.name } Text { text: " Cost: $" + model.cost } } }
注: Qt Quickとは異なり 、ListModel およびListElement は読み取り専用です。つまり、このようなモデルに格納されている値を変更することはできません。編集可能なモデルが必要な場合は、「Qul::ListModel 」および「C++コードとQMLの統合」を参照してください。
オブジェクトのリスト
オブジェクトリテラルを含む配列リテラルをモデルとして使用できます。配列の現在の要素は、modelData ロールとして利用可能であり、直接、またはmodel.modelData としてアクセスできます。
ListView { anchors.fill: parent model: [ { name: "Apple", color: "green" }, { name: "Pear", color: "pink" } ] delegate: Row { width: parent.width / 2 height: parent.height / 2 Text { text: "Fruit: " + modelData.name } Text { text: " Color: " + model.modelData.color } } }
ListModel<T>型のプロパティ
ListModel<T> 型のプロパティをモデルとして使用できます。この場合、T のプロパティがモデルの構造を記述します。
これにより、モデルデータは外部から、あるいはState 内のPropertyChanges によって設定することが可能になります。
// MyView.qml Item { width: 120 height: 40 property ListModel<NameAgeType> myModel ListView { anchors.fill: parents model: myModel delegate: Text { width: parent.width / myModel.count height: parent.height / myModel.count text: model.name } } }
// User.qml Rectangle { Row { MyView { myModel: [{ name: "John Smith", age: 42 }] } MyView { myModel: ListModel { ListElement { name: "Smith"; age: 42 } } } } }
注: ListModel<T> 型は Qt Quick Ultraliteに固有のものであり、Qt Quick には存在しません。これを使用すると、QMLコードはQt Quick と互換性がなくなります。これを使用しない場合、別のファイルでモデルを宣言することはできません。
モデルとしての整数
整数は、特定の数の型を含むモデルとして使用できます。この場合、モデルにはデータロールは存在しません。
次の例では、5つの要素を持つListView を作成しています:
Rectangle { Component { id: itemDelegate Text { width: listView.width / 5 height: listView.height / 5 text: "I am item number: " + index } } ListView { id: listView anchors.fill: parent model: 5 delegate: itemDelegate } }
注: 整数モデルに含まれる項目の数には、1億という制限があります。
C++ データモデル
モデルはC++で定義し、QMLから利用できるようにすることができます。この仕組みは、既存のC++データモデルや、変更可能なデータセット、あるいはその他の複雑なデータセットをQMLに公開するのに役立ちます。
詳細については、「Qul::ListModel 」および「C++コードとQMLの統合」をご覧ください。
特定の Qt ライセンスの下で利用可能です。
詳細はこちらをご覧ください。