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

- モデル- データとその構造を格納します。モデルを作成するための QML 型はいくつかあります。
- ビュー- データを表示するコンテナです。ビューは、データをリストやグリッドで表示することがあります。
- デリゲート- データがビューにどのように表示されるかを指定します。デリゲートは、モデル内の各データ単位を受け取り、それをカプセル化します。データへのアクセスはデリゲートを介して行われます。また、デリゲートは編集可能なモデルにデータを書き戻すこともできます(例:TextField のonAcceptedハンドラ内)。
データを可視化するには、ビューの `model ` プロパティをモデルにバインドし、`delegate ` プロパティをコンポーネントまたはその他の互換性のある型にバインドします。
ビューによるデータの表示
ビューは、項目のコレクションを格納するコンテナです。豊富な機能を備えており、スタイルや動作の要件に合わせてカスタマイズすることができます。
Qt Quick の基本的なグラフィカルタイプには、一連の標準ビューが用意されています:
- ListView - アイテムを水平または垂直のリストに配置します
- GridView - 利用可能なスペース内で、アイテムをグリッド状に配置します
- PathView - 項目をパス上に配置する
- TableView - 「QAbstractTableModel 」のデータを表形式で配置する
- TreeView -QAbstractItemModel からのデータをツリー形式で配置する
これらのタイプには、それぞれ固有のプロパティや動作があります。詳細については、各タイプのドキュメントをご覧ください。
さらに、Qt Quick Controlsには、アプリケーションのスタイルに合わせてデザインされた追加のビューやデリゲートが含まれています。例としては、HorizontalHeaderView やVerticalHeaderView などがあります。
ビューの装飾
ビューでは、header 、footer 、section などのデコレーションプロパティを通じて、視覚的なカスタマイズが可能です。これらのプロパティにオブジェクト(通常は別のビジュアルオブジェクト)をバインドすることで、ビューをデコレートできるようになります。たとえば、フッターには境界線を表示するRectangle タイプを含めたり、ヘッダーにはリストの上部にロゴを表示させたりすることができます。
ある特定のクラブが、会員リストを自クラブのブランドカラーで装飾したいと仮定します。会員リストはmodel に格納されており、delegate がそのモデルの内容を表示します。
ListModel {
id: nameModel
ListElement { name: "Alice" }
ListElement { name: "Bob" }
ListElement { name: "Jane" }
ListElement { name: "Harry" }
ListElement { name: "Wendy" }
}
Component {
id: nameDelegate
Text {
required property string name
text: name
font.pixelSize: 24
width: ListView.view.width
}
}そのクラブは、header およびfooter のプロパティにビジュアルオブジェクトをバインドすることで、メンバーリストを装飾することができます。ビジュアルオブジェクトは、インラインで、別のファイル内で、またはComponent 型内で定義することができます。
ListView {
anchors.fill: parent
clip: true
model: nameModel
delegate: nameDelegate
header: bannercomponent
footer: Rectangle {
width: parent.width; height: 30;
gradient: clubcolors
}
highlight: Rectangle {
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 コンテンツはセクションごとにグループ化することができ、関連するリスト項目はそのセクションに応じてラベル付けされます。さらに、セクションにはデリゲートを適用して装飾を加えることができます。
リストには、人物の名前と、その人物が所属するチームを示すリストが含まれる場合があります。
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 {
required property string name
text: name;
font.pixelSize: 24
anchors.left: parent.left
anchors.leftMargin: 2
}
}ListView 型には、隣接するタイプや関連するタイプをセクションとして結合できるsection という添付プロパティがあります。section.property は、どのリストタイプのプロパティをセクションとして使用するかを決定します。section.criteria はセクション名の表示方法を指定でき、section.delegate はビューのdelegateプロパティと同様の機能を持ちます。
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
}
}
}
}
ビューデリゲート
ビューは、リスト内の項目を視覚的に表現するためにデリゲートを必要とします。ビューは、デリゲートによって定義されたテンプレートに従って、各リスト項目を可視化します。モデル内の項目には、index プロパティおよび項目のプロパティを通じてアクセスできます。
Component {
id: petdelegate
Text {
id: label
font.pixelSize: 24
text: index === 0 ? type + " (default)" : type
required property int index
required property string type
}
}
ビューデリゲートの配置
項目の配置方法は、ビューの型によって決まります。ListView では、orientation の設定に応じて項目が直線上に配置されますが、GridView では、2次元のグリッド上に配置することができます。x やy に直接バインドすることは推奨されません。これは、ビューのレイアウト動作が、位置に関するバインドよりも常に優先されるためです。
デリゲートからのビューおよびモデルへのアクセス
デリゲートがバインドされているリストビューには、デリゲートからListView.view プロパティを介してアクセスできます。同様に、GridView GridView.view もデリゲートから利用可能です。したがって、対応するモデルとそのプロパティには、ListView.view.model を通じてアクセスできます。さらに、モデル内で定義されたシグナルやメソッドにもアクセス可能です。
この仕組みは、例えば、複数のビューで同じデリゲートを使用したいが、各ビューごとに装飾やその他の機能を異ならせたい場合、そしてこれらの異なる設定を各ビューのプロパティとして扱いたい場合に役立ちます。同様に、モデルのプロパティにアクセスしたり、表示したりすることも有用な場合があります。
次の例では、デリゲートがモデルのlanguageプロパティを表示し、フィールドの 1 つの色はビューのfruit_colorプロパティに応じて変化します。
Rectangle {
width: 200; height: 200
ListModel {
id: fruitModel
property string language: "en"
ListElement {
name: "Apple"
cost: 2.45
}
ListElement {
name: "Orange"
cost: 3.25
}
ListElement {
name: "Banana"
cost: 1.95
}
}
Component {
id: fruitDelegate
Row {
id: fruit
required property string name
required property real cost
Text {
text: " Fruit: " + fruit.name
color: fruit.ListView.view.fruit_color
}
Text {
text: " Cost: $" + fruit.cost
}
Text {
text: " Language: " + fruit.ListView.view.model.language
}
}
}
ListView {
property color fruit_color: "green"
model: fruitModel
delegate: fruitDelegate
anchors.fill: parent
}
}モデル
データは、デリゲートがバインドできる名前付きデータロールを通じてデリゲートに提供されます。以下は、`type`と`age`という2つのロールを持つListModel と、これらのロールにバインドしてその値を表示するデリゲートを持つListView の例です:
import QtQuick
Item {
width: 200
height: 250
ListModel {
id: myModel
ListElement { type: "Dog"; age: 8; noise: "meow" }
ListElement { type: "Cat"; age: 5; noise: "woof" }
}
component MyDelegate : Text {
required property string type
required property int age
text: type + ", " + age
// WRONG: Component.onCompleted: () => console.log(noise)
// The above line would cause a ReferenceError
// as there is no required property noise,
// and the presence of the required properties prevents
// noise from being injected into the scope
}
ListView {
anchors.fill: parent
model: myModel
delegate: MyDelegate {}
}
}ほとんどの場合、モデルデータをデリゲートに渡すには、必須プロパティを使用する必要があります。デリゲートに必須プロパティが含まれている場合、QMLエンジンは、その必須プロパティの名前がモデルのロールの名前と一致するかどうかを確認します。一致する場合、そのプロパティはモデルからの対応する値にバインドされます。
ごく稀な特殊なケースでは、必須プロパティとしてではなく、QMLコンテキストを介してモデルプロパティを渡したい場合があります。デリゲートに必須プロパティが存在しない場合、名前付きロールはコンテキストプロパティとして提供されます:
import QtQuick
Item {
width: 200; height: 250
ListModel {
id: myModel
ListElement { type: "Dog"; age: 8 }
ListElement { type: "Cat"; age: 5 }
}
Component {
id: myDelegate
Text { text: type + ", " + age }
}
ListView {
anchors.fill: parent
model: myModel
delegate: myDelegate
}
}コンテキストプロパティはツールからは認識されず、Qt Quick コンパイラによるコードの最適化を妨げます。また、デリゲートが期待する具体的なデータについて推論しにくくなります。 QML から QML コンテキストに明示的にデータを設定する方法はありません。コンポーネントが QML コンテキスト経由でのデータ受け渡しを想定している場合、ネイティブな手段によって適切なコンテキストが利用可能になる場所でのみ、それを使用できます。これには、自身の C++ コードや、周囲の要素の特定の実装が含まれます。 一方、必須のプロパティは、QML から、あるいはネイティブな手段を通じて、さまざまな方法で設定できます。したがって、QML コンテキストを介してデータを渡すことは、コンポーネントの再利用性を低下させることになります。
モデルのプロパティとデリゲートのプロパティの間で命名上の競合がある場合、代わりに修飾されたモデル名を使用してロールにアクセスできます。たとえば、Text 型に(必須ではない)typeやageというプロパティがあった場合、上記の例のテキストには、モデル項目のtypeやageの値ではなく、それらのプロパティの値が表示されます。 この場合、デリゲートがモデル項目のプロパティ値を確実に表示するように、プロパティをmodel.type やmodel.age として参照することもできました。これを機能させるには、デリゲート内でmodel プロパティを必須にする必要があります(コンテキストプロパティを使用している場合を除く)。
また、デリゲートでは、モデル内の項目のインデックスを含む特別なインデックスロールも利用可能です。なお、項目がモデルから削除された場合、このインデックスは -1 に設定されることに注意してください。 インデックスロールにバインドする場合は、インデックスが -1 になる可能性、つまりそのアイテムがもはや有効ではない可能性をロジックで考慮するようにしてください。(通常、そのアイテムはまもなく破棄されますが、delayRemove というアタッチドプロパティを使用することで、一部のビューにおいてデリゲートの破棄を遅延させることも可能です。)
モデルとして整数や配列を使用できることに注意してください:
Repeater {
model: ["one", "two", "three"]
Text {
required property string modelData
text: modelData
}
}このようなモデルは、デリゲートの各インスタンスに対して、単一の匿名データを提供します。このデータにアクセスすることが、modelData を使用する主な理由ですが、他のモデルもmodelData を提供しています。
モデルロールを通じて提供されるオブジェクトには、名前が空のプロパティがあります。この無名のプロパティには、modelData が格納されています。さらに、モデルロールを通じて提供されるオブジェクトには、modelData という名前の別のプロパティもあります。このプロパティは非推奨となっており、こちらもmodelData を格納しています。
modelロールに加えて、modelDataロールも提供されています。modelDataロールは、modelDataプロパティおよび modelロールを通じて提供されるオブジェクトの匿名プロパティと同じデータを保持しています。
modelロールと、modelDataにアクセスするためのさまざまな方法との違いは以下の通りです:
- 名前付きロールを持たないモデル(整数や文字列の配列など)の場合、そのデータはmodelDataロールを介して提供されます。この場合、modelDataロールは必ずしもオブジェクトを含むとは限りません。 整数モデルの場合は、整数(現在のモデル項目のインデックス)が含まれます。文字列の配列の場合は、文字列が含まれます。modelロールには依然としてオブジェクトが含まれていますが、名前付きロール用のプロパティはありません。ただし、modelには通常どおりmodelDataプロパティと匿名プロパティが含まれています。
- モデルに名前付きロールが 1 つしかない場合、modelDataロールにはその名前付きロールと同じデータが含まれます。これは必ずしもオブジェクトであるとは限らず、通常のように名前付きプロパティとしてその名前付きロールを含むこともありません。この場合でも、modelロールには、名前付きロールをプロパティとするオブジェクトと、modelDataプロパティおよび匿名プロパティが含まれます。
- 複数のロールを持つモデルの場合、modelDataロールはコンテキストプロパティとしてではなく、必須プロパティとしてのみ提供されます。これは、古いバージョンのQtとの下位互換性を確保するためです。
model上の匿名プロパティを使用すると、モデルデータと、反応すべきロール名の両方を外部からのプロパティとして受け取るデリゲートを、すっきりとした形で記述できます。named ロールを一切持たない、あるいは 1 つだけ持つモデルを、role として空の文字列を指定して提供することができます。そうすれば、単に `model[role] ` にアクセスするバインディングでも、期待通りの動作をします。 このケースでは、特別なコードを追加する必要はありません。
注: デリゲートに必須プロパティが含まれている場合、model、index、およびmodelDataの各ロールには アクセスできません。ただし、デリゲート側に名前が一致する必須プロパティが存在する場合はこの限りではありません。
QML には、組み込みの QML 型セットの中にいくつかの種類のデータモデルが用意されています。さらに、Qt C++ を使用してモデルを作成し、QQmlEngine で利用可能にして、QML コンポーネントから使用できるようにすることもできます。これらのモデルの作成方法については、「 Qt Quick ビューでの C++ モデルの使用」および「QML 型の作成」の記事をご覧ください。
モデルからの項目の配置は、Repeater を使用して実現できます。
リストモデル
ListModel は、QMLで定義されたタイプの単純な階層構造です。利用可能なロールは、ListElement のプロパティによって指定されます。
ListModel {
id: fruitModel
ListElement {
name: "Apple"
cost: 2.45
}
ListElement {
name: "Orange"
cost: 3.25
}
ListElement {
name: "Banana"
cost: 1.95
}
}上記のモデルには、「name」と「cost」という2つのロールがあります。これらは、ListView デリゲートによってバインドすることができます。例えば、次のようにします。
ListView {
anchors.fill: parent
model: fruitModel
delegate: Row {
id: delegate
required property string name
required property real cost
Text { text: "Fruit: " + delegate.name }
Text { text: "Cost: $" + delegate.cost }
}
}ListModel は、JavaScript を通じて `ListModel ` を直接操作するためのメソッドを提供します。この場合、最初に挿入された項目によって、そのモデルを使用するすべてのビューで利用可能なロールが決定されます。例えば、空の `ListModel ` が作成され、JavaScript を通じてデータが設定された場合、最初に挿入された項目によって提供されたロールのみがビューに表示されます:
ListModel { id: fruitModel }
...
MouseArea {
anchors.fill: parent
onClicked: fruitModel.append({"cost": 5.95, "name":"Pizza"})
}MouseArea がクリックされると、fruitModel には「cost」と「name」の2つのロールが設定されます。その後、さらにロールが追加されたとしても、このモデルを使用するビューでは最初の2つのロールのみが処理されます。モデルで利用可能なロールをリセットするには、ListModel::clear() を呼び出してください。
XMLモデル
XmlListModel を使用すると、XML データソースからモデルを構築できます。ロールは `XmlListModelRole ` タイプを介して指定されます。このタイプはインポートする必要があります。
import QtQml.XmlListModel以下のモデルには、title、link、pubDate の 3 つのロールがあります:
XmlListModel {
id: feedModel
source: "http://rss.news.yahoo.com/rss/oceania"
query: "/rss/channel/item"
XmlListModelRole { name: "title"; elementName: "title" }
XmlListModelRole { name: "link"; elementName: "link" }
XmlListModelRole { name: "pubDate"; elementName: "pubDate" }
}query プロパティは、XmlListModel がXMLドキュメント内の各<item> に対してモデル項目を生成することを指定します。
「RSS News」デモでは、XmlListModel を使用してRSSフィードを表示する方法を示しています。
オブジェクトモデル
ObjectModel には、ビューで使用される視覚的なアイテムが含まれています。ビューでObjectModel が使用される場合、ObjectModel にはすでに視覚的なデリゲート(アイテム)が含まれているため、そのビューにデリゲートを設定する必要はありません。
以下の例では、ListView 内に3つの色付き長方形を配置しています。
import QtQuick 2.0
import QtQml.Models 2.1
Rectangle {
ObjectModel {
id: itemModel
Rectangle { height: 30; width: 80; color: "red" }
Rectangle { height: 30; width: 80; color: "green" }
Rectangle { height: 30; width: 80; color: "blue" }
}
ListView {
anchors.fill: parent
model: itemModel
}
}モデルとしての整数
整数は、特定の数の型を含むモデルとして使用できます。この場合、モデルにはデータロールは存在しません。
次の例では、5つの要素を持つListView を作成しています:
Item {
width: 200; height: 250
Component {
id: itemDelegate
Text {
required property int index
text: "I am item number: " + index
}
}
ListView {
anchors.fill: parent
model: 5
delegate: itemDelegate
}
}注: 整数モデルに含まれる項目の数には、1億という上限があります。
モデルとしてのオブジェクトインスタンス
オブジェクトインスタンスを使用すると、単一のオブジェクト型を持つモデルを指定できます。オブジェクトのプロパティはロールとして提供されます。
以下の例では、1つの項目を含むリストを作成し、「myText」というテキストの色を表示しています。デリゲート内のText型が持つcolorプロパティとの衝突を避けるため、完全修飾されたmodel.colorプロパティが使用されている点に注意してください。
Rectangle {
width: 200; height: 250
Text {
id: myText
text: "Hello"
color: "#dd44ee"
}
Component {
id: myDelegate
Text {
required property var model
text: model.color
}
}
ListView {
anchors.fill: parent
anchors.topMargin: 30
model: myText
delegate: myDelegate
}
}C++ データモデル
モデルは C++ で定義し、QML から利用できるようにすることができます。この仕組みは、既存の C++ データモデルや、それ以外の複雑なデータセットを QML に公開するのに役立ちます。
詳細については、「 Qt Quick ビューでのC++モデルの使用」の記事をご覧ください。
配列モデル
JavaScriptの配列や、さまざまな種類のQMLリストをモデルとして使用できます。リストの要素は、前述のルールに従ってmodelおよびmodelDataとして利用可能になります。整数や文字列のような単一のデータは、単一のmodelDataとして利用可能になります。JavaScriptオブジェクトやQObjectのような構造化されたデータは、構造化されたmodelおよびmodelDataとして利用可能になります。
個々のモデルロールも、必須プロパティとして要求すれば利用可能になります。配列にどのようなオブジェクトが含まれるかは事前にわからないため、デリゲート内の必須プロパティには、必要に応じてundefined が要求される型に強制変換されて値が設定されます。ただし、個々のモデルロールはQMLコンテキスト経由では利用できません。それらは他のすべてのコンテキストプロパティをオーバーライドしてしまうためです。
リピーター

リピーターは、モデルからのデータを使用して、ポジショナーで利用するためのテンプレートからアイテムを作成します。リピーターとポジショナーを組み合わせることで、多数のアイテムを簡単にレイアウトできます。Repeater アイテムをポジショナー内に配置すると、そのアイテムが生成され、外側のポジショナーによって配置されます。
各リピーターは、model プロパティで指定されたモデルからの各データ要素と、リピーター内の子アイテムとして定義されたテンプレートアイテムを組み合わせることで、複数のアイテムを作成します。アイテムの総数は、モデル内のデータ量によって決まります。
次の例は、Gridアイテムと組み合わせて一連のRectangleアイテムを配置するために使用されるRepeaterを示しています。Repeaterアイテムは24個の矩形を作成し、Gridアイテムがそれらを5×5の配列で配置します。
import QtQuick
Rectangle {
width: 400
height: 400
color: "black"
Grid {
x: 5
y: 5
rows: 5
columns: 5
spacing: 10
Repeater {
model: 24
Rectangle {
id: delegate
required property int index
width: 70
height: 70
color: "lightgreen"
Text {
text: delegate.index
font.pointSize: 30
anchors.centerIn: parent
}
}
}
}
}Repeater によって生成されるアイテムの数は、その `count ` プロパティに保持されます。このプロパティを設定して生成されるアイテムの数を指定することはできません。その代わりに、上記の例のように、モデルとして整数を使用します。
詳細については、QMLデータモデルに関するドキュメントを参照してください。
モデルが文字列のリストである場合、その文字列を保持する通常の読み取り専用プロパティ `modelData ` もデリゲートとして公開されます。例:
|
また、デリゲートを、Repeaterによって作成される項目のテンプレートとして使用することも可能です。これは、delegate プロパティを使用して指定します。
モデルデータの変更
関連するすべてのビューには、デリゲートからモデルデータを変更できるかどうか、およびその方法を制御するdelegateModelAccessというプロパティがあります。 ほとんどのユースケースでは、このプロパティを `DelegateModel.ReadWrite` に設定することをお勧めします。これにより、デリゲートが最も柔軟な方法でモデルデータを変更できるようになります。一方、デリゲートによるモデルデータの変更を一切許可したくない場合は、`DelegateModel.ReadOnly` に設定することもできます。
次の表は、このプロパティが取り得るすべての値について詳しく説明しています。
| DelegateModel.Qt5ReadWrite | デリゲートは、関連するモデル項目を変更するために、ビューによって提供される任意のコンテキストプロパティに値を割り当てることができます。さらに、同様の効果を得るために、コンテキストプロパティまたは必須プロパティとして提供される `model ` オブジェクトのプロパティに値を割り当てることもできます。ただし、デリゲートは、ビューによって初期化された必須プロパティに値を割り当てることでモデルデータを変更することはできません。 デリゲートの必須プロパティに値を代入すると、モデルデータからその必須プロパティを更新するバインディングが破綻します。これにより、後でモデルが変更された場合でも、その必須プロパティは代入された値を保持したままになります。DelegateModel.Qt5ReadWrite は、delegateModelAccess のデフォルト値です。 |
| DelegateModel.ReadOnly | デリゲートは、ビューによって提供されるコンテキストプロパティに値を割り当てることはできず、model オブジェクトのプロパティに値を割り当てることもできません。ビューによって設定された必須プロパティに値を割り当てても、内部のバインディングは破綻せず、モデルデータも変更されません。その必須プロパティは、モデル項目が再び変更されるまで、割り当てられた値を保持し続けます。 |
| DelegateModel.ReadWrite | デリゲートは、関連するモデル項目を変更するために、ビューによって提供される任意のコンテキストプロパティに値を割り当てることができます。さらに、コンテキストプロパティまたは必須プロパティとして提供されるmodel オブジェクトのプロパティにも同様に値を割り当てることができます。 また、デリゲートは、ビューによって設定された必須プロパティに値を割り当てることで、モデルデータを変更することもできます。必須プロパティに値を割り当てると、その値は対応するモデル項目に反映され、内部バインディングは破られません。 |
一部のモデルは、ビューが参照する独立した識別子を持つオブジェクトです。元のオブジェクトは、デリゲートを作成するための唯一の「真実の源」であり、コピーされることはありません。このようなモデルは、デリゲートを介して書き込みを行うと、目に見える形で更新されます。
一方、独立した識別を持たないモデルもあり、これらはビューに割り当てる際にコピーされます。このようなモデルの場合、デリゲートを通じて書き込みを行うと、ビューの内部のみが更新されます。元のモデルは変更されません。
一般的に、QMLのオブジェクト型は独立した識別子を持っていますが、QMLの値型は持っていません。 したがって、ListModel 、QAbstractItemModel から派生したすべての型、およびオブジェクト型の単一インスタンスまたは オブジェクト型のインスタンスのリストは、モデルとして渡され、デリゲートを通じて書き込みが行われると更新されます。一方、JavaScript 配列、値型のリスト、または単純な数値は、デリゲートを介してモデルデータを変更しても更新されません。
さらに、独自の C++ モデルを実装する際は、デリゲートから渡される更新を受け取るために、setData を実装する必要があります。
setData メソッドを実装したQAbstractItemModel ベースのC++モデルが、EditableModel という名前のQML型として登録されていると仮定します。その場合、モデルへの書き込みは次のように行えます:
ListView {
anchors.fill: parent
model: EditableModel {}
// Make sure that changes to the required property are propagated
delegateModelAccess: DelegateModel.ReadWrite
delegate: TextEdit {
required property string edit
width: ListView.view.width
height: 30
text: edit
Keys.onReturnPressed: edit = text
}
}また、次のようにmodel オブジェクトを操作して、モデルのデータを変更することもできます:
ListView {
anchors.fill: parent
model: EditableModel {}
delegate: TextEdit {
required property QtObject model
width: ListView.view.width
height: 30
text: model.edit
Keys.onReturnPressed: model.edit = text
}
}注: edit ロールは 、Qt::EditRole に相当します。組み込みのロール名については、roleNames()を参照してください。ただし、実際のモデルでは通常、カスタムロールを登録することになります。
詳細については、「 Qt Quick ビューでのC++モデルの使用」の記事を参照してください。
遷移の使用
トランジションを使用すると、ポジショナーに追加されたり、ポジショナー内で移動したり、ポジショナーから削除されたりするアイテムにアニメーションを適用できます。
アイテムの追加に関するトランジションは、ポジショナーの一部として作成されたアイテムだけでなく、ポジショナーの子となるよう親を変更されたアイテムにも適用されます。
アイテムの削除に関するトランジションは、ポジショナー内で削除されるアイテムだけでなく、ポジショナーから削除され、ドキュメント内で新しい親が指定されるアイテムにも適用されます。
注: アイテムの不透明度をゼロに変更しても 、そのアイテムはポジショナーから消えることはありません。visible プロパティを変更することで、アイテムを削除したり再追加したりすることができます。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.
