📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

編集の要約なし
 
(同じ利用者による、間の2版が非表示)
399行目: 399行目:
加えて、モデルはQt C++で作成することができ、そのモデルを<code>QQmlEngine</code>クラスを使用してQMLコンポーネントから利用することもできる。<br>
加えて、モデルはQt C++で作成することができ、そのモデルを<code>QQmlEngine</code>クラスを使用してQMLコンポーネントから利用することもできる。<br>
<br>
<br>
モデルの作成については、[[QMLの基礎 - モデルの作成]]や[[QMLの基礎 - QMLタイプの作成]]を参照すること。<br>
モデルの作成については、[[QMLの基礎 - モデルの作成]]や[[QMLの基礎 - カスタムQMLタイプ]]を参照すること。<br>
<br>
<br>
モデルからアイテムを配置する場合は、<code>Repeater</code>を使用することで実現できる。<br>
モデルからアイテムを配置する場合は、<code>Repeater</code>を使用することで実現できる。<br>
<br>
==== ListModel ====
<code>ListModel</code>は、QMLで指定された単純な型の階層である。<br>
利用可能な役割は、<code>ListElement</code>プロパティで指定する。<br>
<syntaxhighlight lang="qml">
ListModel {
    id: fruitModel
    ListElement {
      name: "Apple"
      cost: 2.45
    }
    ListElement {
      name: "Orange"
      cost: 3.25
    }
    ListElement {
      name: "Banana"
      cost: 1.95
    }
}
</syntaxhighlight>
<br>
上記の<code>ListModel</code>は、nameロールとcostロールの2つのロールを持っている。<br>
これらは、例えば、<code>ListView</code>のデリゲートでバインドすることができる。<br>
<syntaxhighlight lang="qml">
ListView {
    anchors.fill: parent
    model: fruitModel
    delegate: Row {
      Text {
          text: "Fruit: " + name
      }
      Text {
          text: "Cost: $" + cost
      }
    }
}
</syntaxhighlight>
<br>
<code>ListModel</code>には、JavaScriptから<code>ListModel</code>を直接操作するためのメソッドが用意されている。<br>
この時、最初に挿入されたアイテムが、モデルを使用している全てのビューで利用可能なロールを決定する。<br>
<br>
例えば、空の<code>ListModel</code>があり、JavaScript経由で入力された場合、最初の挿入によって提供されたロールがビューに表示される唯一のロールとなる。<br>
<br>
以下の例では、初めて<code>MouseArea</code>の場所が押下する時、fruitModel(<code>ListModel</code>)にはcostロールとnameロールの2つのロールが追加される。<br>
次のロールが追加された場合も、モデルを使用するビューでは、最初の2つのロールのみが処理される。<br>
<br>
モデルで利用可能なロールをリセットするには、<code>ListModel::clear</code>メソッドを呼び出す必要がある。<br>
<syntaxhighlight lang="qml">
ListModel {
    id: fruitModel
}
// ...略
MouseArea {
    anchors.fill: parent
    onClicked: {
      fruitModel.append({"cost": 5.95, "name":"Pizza"})
    }
}
</syntaxhighlight>
<br>
==== XmlListModel ====
<code>XmlListModel</code>では、XMLデータソースからモデルを構築することができる。<br>
ロールは、<code>XmlRole</code>型で指定する。<br>
<br>
<code>XmlListModel</code>は、以下のモジュールをインポートする必要がある。<br>
<syntaxhighlight lang="qml">
import QtQuick.XmlListModel 2.15
</syntaxhighlight>
<br>
以下の例では、タイトル、リンク、説明の3つのロールを持っている。<br>
<code>query</code>プロパティは、<code>XmlListModel</code>がXMLドキュメント内の各<code><item></code>エレメントに対して、モデルアイテムを生成することを指定する。<br>
<syntaxhighlight lang="qml">
XmlListModel {
    id: feedModel
    source: "http://rss.news.yahoo.com/rss/oceania"
    query: "/rss/channel/item"
    XmlRole {
      name: "title"
      query: "title/string()"
    }
    XmlRole {
      name: "link"
      query: "link/string()"
    }
    XmlRole {
      name: "description"
      query: "description/string()"
    }
}
</syntaxhighlight>
<br>
[https://doc.qt.io/qt-5/qtdoc-demos-rssnews-example.html RSSニュースのデモ]では、<code>XmlListModel</code>を使用してRSSフィードを表示する方法を記載している。<br>
<br>
==== ObjectModel ====
<code>ObjectModel</code>は、ビューで使用されるビジュアルアイテムを含んでいる。<br>
<code>ObjectModel</code>をビューで使用する場合、<code>ObjectModel</code>には既に視覚的なデリゲート(アイテム)が含まれているため、ビューはデリゲートを必要としない。<br>
<br>
以下の例では、3つの色付きの長方形を<code>ListView</code>に配置している。<br>
<syntaxhighlight lang="qml">
import QtQuick 2.15
import QtQml.Models 2.15
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
    }
}
</syntaxhighlight>
<br>
==== 整数型モデル ====
整数は、ある数の型を含むモデルとして使用できる。<br>
この場合、モデルにはデータの役割はありません。<br>
<br>
以下の例では、5つの要素を持つ<code>ListView</code>を作成している。<br>
<br>
<u>※注意</u><br>
<u>整数モデルのアイテム数の制限は、100,000,000であることに注意すること。</u><br>
<syntaxhighlight lang="qml">
Item {
    width: 200
    height: 250
    ListView {
      anchors.fill: parent
      model: 5
      delegate: itemDelegate
    }
    Component {
      id: itemDelegate
      Text {
          text: "I am item number: " + index
      }
    }
}
</syntaxhighlight>
<br>
==== C++データモデル ====
C++でモデルを定義して、それをQMLで使用することができる。<br>
この仕組みは、既存のC++データモデルや複雑なデータセットをQMLに公開するのに便利である。<br>
<br>
詳細は、[https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html Using C++ Models with Qt Quick Views]の記事を参照すること。<br>
<br><br>
== Repeater ==
<code>Repeater</code>は、モデルのデータをもとに、ポジショナで使用するアイテムをテンプレートから作成する。<br>
<code>Repeater</code>とポジショナを組み合わせることで、多くのアイテムを簡単に並べることができる。<br>
<br>
<code>Repeater</code>はポジショナの中に配置されて、ポジショナが配置したアイテムを生成する。<br>
<br>
各<code>Repeater</code>は、モデルのプロパティで指定されたモデルのデータの各要素、および、<code>Repeater</code>内の子アイテムとして定義されたテンプレートアイテムを組み合わせて、多数のアイテムを作成する。<br>
アイテムの総数は、モデルのデータ量によって決まる。<br>
<br>
以下の例では、<code>Grid</code>内で<code>Repeater</code>を使用して、<code>Rectangle</code>を格子状に配置している。<br>
<code>Repeater</code>は、<code>Grid</code>が5x5の配列で配置しており、計24個の<code>Rectangle</code>を作成している。<br>
<syntaxhighlight lang="qml">
import QtQuick 2.15
Rectangle {
    width: 400
    height: 400
    color: "black"
    Grid {
      x: 5
      y: 5
      rows: 5
      columns: 5
      spacing: 10
      Repeater {
          model: 24
          Rectangle {
            width: 70
            height: 70
            color: "lightgreen"
            Text {
                text: index
                font.pointSize: 30
                anchors.centerIn: parent
            }
          }
      }
    }
}
</syntaxhighlight>
<br>
<code>Repeater</code>が作成するアイテムの数は<code>Repeater.count</code>プロパティで保持されるが、このプロパティは読み込み専用のため設定することができない。<br>
そのため、上記の例のように、<code>Repeater.model</code>プロパティにアイテムの数を設定する。<br>
<br>
モデルが文字列リストの場合、デリゲートは文字列を保持する読み取り専用の<code>Repeater.modelData</code>プロパティにも保持される。<br>
以下の例では、<code>Repeater.model</code>プロパティのリスト配列を<code>Text.text</code>プロパティに順に設定して、<code>Text</code>を配置している。<br>
[[ファイル:QML Model and View 5.png|フレームなし|中央]]
<syntaxhighlight lang="qml">
Column {
    Repeater {
      model: ["apples", "oranges", "pears"]
      Text {
          text: "Data: " + modelData
      }
    }
}
</syntaxhighlight>
<br>
また、<code>Repeater</code>が作成するアイテムのテンプレートとして、デリゲートを使用することもできる。<br>
これは、<code>delegate</code>プロパティで指定する。<br>
<br><br>
== モデルデータの変更 ==
モデルのデータを変更するには、モデルのプロパティに最新の値を割り当てる。<br>
QMLの<code>ListModel</code>はデフォルトで編集可能であるが、C++のモデルは<code>setData</code>メソッドを実装しないと編集できない。<br>
なお、整数やJavaScriptの配列モデルは、読み取り専用である。<br>
<br>
以下の例では、EditableModelは<code>QAbstractItemModel</code>を継承したC++モデルで<code>setData</code>メソッドを実装しており、かつ、QML型として登録されている場合、<br>
データは、以下のようにモデルに書き込まれまる。<br>
<syntaxhighlight lang="qml">
ListView {
    anchors.fill: parent
    model: EditableModel {}
    delegate: TextEdit {
      width: ListView.view.width
      height: 30
      text: model.edit
      Keys.onReturnPressed: {
          model.edit = text
      }
    }
}
</syntaxhighlight>
<br>
<u>※注意</u><br>
<u><code>edit</code>ロールは、<code>Qt::EditRole</code>と同じである。組み込みのロール名については、[https://doc.qt.io/qt-5/qabstractitemmodel.html#roleNames roleNames()]を参照すること。</u><br>
<u>実際のモデルでは、通常、カスタムロールを登録する。</u><br>
<br>
モデルのロールが<code>required <プロパティ名></code>にバインドされている場合、そのプロパティに割り当ててもモデルは変更されない。<br>
代わりに、モデルへのバインドが解除される。(他のプロパティへの割り当てが既存のバインドを解除するのと同様である)<br>
<br>
必須プロパティを使用してモデルデータを変更する場合、<code>model</code>も必須プロパティにして<code>model.propertyName</code>に割り当てる。<br>
<br>
詳細は、[https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html#changing-model-data Using C++ Models with Qt Quick Views]を参照すること。<br>
<br><br>
== トランジションの使用 ==
トランジションは、ポジショナに追加、ポジショナ内での移動、ポジショナから削除されたアイテムをアニメーション化するために使用する。<br>
<br>
アイテムを追加するトランジションは、ポジショナの一部として作成されたアイテムや、ポジショナの子になるために再配置されたアイテムに適用される。<br>
アイテムを削除するためのトランジションは、ポジショナ内のアイテムが削除された場合や、ポジショナから削除されてドキュメント内に新しい親が与えられた場合に適用される。<br>
<br>
<u>※注意</u><br>
<u>アイテムの不透明度をゼロに変更しても、ポジショナからアイテムが消えることはない。</u><br>
<u>これらのアイテムは、<code>visible</code>プロパティを変更することで、削除および追加することができる。</u><br>
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:Qt]]
[[カテゴリ:Qt]]