12,788
回編集
編集の要約なし |
|||
198行目: | 198行目: | ||
<br> | <br> | ||
[[ファイル:QML Model and View 3.png|フレームなし|中央]] | [[ファイル:QML Model and View 3.png|フレームなし|中央]] | ||
<br><br> | |||
== ビューのデリゲート == | |||
ビューは、リストの中のアイテムを視覚的に表現するために、デリゲートが必要となる。<br> | |||
<br> | |||
ビューは、デリゲートにより定義されたテンプレートにしたがって、各アイテムのリストを生成する。<br> | |||
モデル内のアイテムは、アイテムのプロパティだけでなく、インデックスのプロパティにもアクセスできる。<br> | |||
[[ファイル:QML Model and View 4.png|フレームなし|中央]] | |||
<br> | |||
<syntaxhighlight lang="qml"> | |||
Component { // delegate: <アイテム名> { を使用することもできる | |||
id: petdelegate | |||
Text { | |||
id: label | |||
font.pixelSize: 24 | |||
text: index === 0 ? type + " (default)" : type | |||
required property int index | |||
required property string type | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<br> | |||
==== デリゲートからのビューやモデルへのアクセス ==== | |||
デリゲートがバインドされているビューは、<code>view</code>プロパティを介してデリゲートからアクセスできる。(例. <code>ListView.view</code>, <code>GridView.view</code>等)<br> | |||
したがって、対応するモデルとそのプロパティは、<code>view.model</code>を通じて使用できる。(例. <code>ListView.view.model</code>, <code>GridView.view.model</code>等)<br> | |||
<br> | |||
さらに、モデルに定義されているシグナルやメソッドもアクセス可能である。<br> | |||
例えば、複数のビューに同じデリゲートを使用したいが、装飾等の機能は各ビューごとに異なるものにする場合や他の異なる設定を各ビューのプロパティにする場合に活用できる。<br> | |||
同様に、モデルの各プロパティにアクセスおよび表示することもできる。<br> | |||
<br> | |||
以下の例では、デリゲート内の1つのTextアイテムは、<code>ListModel</code>内のlanguageプロパティを表示している。<br> | |||
また、デリゲート内の1つのTextアイテムの色は、<code>ListView</code>内のfruit_colorプロパティに依存している。<br> | |||
<syntaxhighlight lang="qml"> | |||
Rectangle { | |||
width: 200 | |||
height: 200 | |||
ListView { | |||
model: fruitModel | |||
delegate: fruitDelegate | |||
anchors.fill: parent | |||
property color fruit_color: "green" | |||
} | |||
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 | |||
Text { | |||
text: " Fruit: " + name | |||
color: fruit.ListView.view.fruit_color | |||
} | |||
Text { | |||
text: " Cost: $" + cost | |||
} | |||
Text { | |||
text: " Language: " + fruit.ListView.view.model.language | |||
} | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
== モデル == | |||
データは、デリゲートがバインドすることができる名前付きのデータロールを介してデリゲートに提供される。<br> | |||
<br> | |||
以下の例では、typeとageという2つのロールを持つListModel、および、これらのロールにバインドして値を表示するデリゲートを持つListViewを作成している。<br> | |||
<syntaxhighlight lang="qml"> | |||
import QtQuick 2.15 | |||
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 | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
ロールのアクセスをより細かく制御する場合、および、デリゲートをビュー外部で使用する場合は、以下のように記述する。<br> | |||
<syntaxhighlight lang="qml"> | |||
required property <データ型> <プロパティ名> | |||
</syntaxhighlight> | |||
<br> | |||
デリゲートに必須プロパティが含まれている場合、名前付きのロールは提供されない。<br> | |||
代わりに、QMLエンジンは、まず、必須プロパティ名がモデルロールの名前と一致するかどうかをチェックして、一致する場合、その必須プロパティはモデルの対応する値にバインドされる。<br> | |||
<syntaxhighlight lang="qml"> | |||
import QtQuick 2.15 | |||
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 | |||
// 間違った記述: Component.onCompleted: () => console.log(noise) | |||
// 必須プロパティであるnoiseがないため、ReferenceErrorが発生する | |||
// 必要プロパティが存在することで、スコープにノイズが注入されるのを防ぐことができる | |||
} | |||
ListView { | |||
anchors.fill: parent | |||
model: myModel | |||
delegate: MyDelegate {} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
モデルのプロパティとデリゲートのプロパティの間に名前の衝突がある場合、代わりに修飾されたモデル名でロールにアクセスすることができる。<br> | |||
<br> | |||
例えば、モデル内とデリゲート内の両方に同名のプロパティが存在する時、<br> | |||
デリゲート内のプロパティではなく、モデル内のプロパティを参照する場合、<code><モデルのID名>.<プロパティ名></code>と記述することにより参照できる。<br> | |||
<br> | |||
また、モデル内のインデックスを含む特別なインデックスロールもデリゲートで使用できる。<br> | |||
<br> | |||
<u>※注意</u><br> | |||
<u>このインデックスは、アイテムがモデルから削除されると<code>-1</code>に設定されることに注意すること。</u><br> | |||
<u>インデックスロールにバインドする場合、インデックスが<code>-1</code>になる可能性、つまり、アイテムが有効でなくなる可能性を考慮したロジックにする。</u><br> | |||
<u>(通常、アイテムはすぐに破棄されるが、一部のビューでは<code>delayRemove</code>プロパティによりデリゲートの破棄を遅らせることができる)</u><br> | |||
<br> | |||
名前付きロールを持たないモデル(例. <code>ListModel</code>等)は、モデルデータロールによりデータが提供される。<br> | |||
モデルデータロールは、1つのロールしか持たないモデルにも提供される。この場合、モデルデータロールには、名前付きロールと同じデータが含まれる。<br> | |||
<br> | |||
<u>※注意</u><br> | |||
<u>モデルロール、モデルデータロール、インデックスロールにおいて、デリゲートが必須プロパティを含んでいる場合、プロパティ名が一致しなければアクセスできないことに注意する。</u><br> | |||
<br> | |||
QMLには、いくつかのデータモデルが用意されており、それらはQMLの組み込み型に含まれている。<br> | |||
加えて、モデルはQt C++で作成することができ、そのモデルを<code>QQmlEngine</code>クラスを使用してQMLコンポーネントから利用することもできる。<br> | |||
<br> | |||
モデルの作成については、[[QMLの基礎 - モデルの作成]]や[[QMLの基礎 - QMLタイプの作成]]を参照すること。<br> | |||
<br> | |||
モデルからアイテムを配置する場合は、<code>Repeater</code>を使用することで実現できる。<br> | |||
<br><br> | <br><br> | ||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:Qt]] | [[カテゴリ:Qt]] |