English French [qt-devnet.developpez.com] 日本語
QML の ListView で列(Column)を作る方法
その列のデータの幅に応じたサイズの複数の列を、ListView に作る方法の一つを説明します。
通常、ListView 内の Row 要素は以下のように表示されます。

Row 要素では幅を設定しながら各列を作成することができます。

文字列の幅の取得
QML にはフォントメトリックスはありません。しかし、JavaScript で Text 要素を動的に生成することで、文字列の幅を取得することができます。
- // 一時的な Text 要素を作成
- parent, "calcTextWidth");
- // textElement.width で文字列(text)の幅を取得
- // 一時要素を破棄
- textElement.destroy()
ListView に列を作る
列の幅は JavaScript でモデルから計算し、モデルの要素名を鍵としてマップに保存します。ListView のデリゲート(delegate)でその幅を用います。
main.qml
ListView のデモ用の簡単な UI です。Rectangle 要素は単にコンテナとして使われていて、各行で表示するのと同じ色を設定してます。columnWidths プロパティにはデリゲートで利用する各列の幅を計算した結果を格納します。
- import Qt 4.7
- import "ColumnHelper.js" as ColumnHelper
- Rectangle {
- width: 620
- height: 200
- color: "#bebebe"
- ListView {
- id: list
- property variant columnWidths: ColumnHelper.calcColumnWidths(model, list)
- anchors.fill: parent
- model: MovieModel { }
- delegate: MovieItem { }
- }
- }
ColumnHelper.js
Text 要素の最大幅を計算するための簡単な JavaScript 関数です。各列の全てのデータで最大幅を計算し、結果を列の名前を鍵としたマップに格納して返します。
- var columns = {}
- function calcColumnWidths(model, parent)
- {
- for (var i = 0; i < model.count; ++i)
- {
- var data = model.get(i)
- for (var key in data)
- {
- if (!columns[key]) {
- columns[key] = 0
- }
- 'import Qt 4.7;'
- + 'Text {'
- + ' text: "' + data[key] + '" '
- + '}',
- parent, "calcColumnWidths")
- columns[key] = Math.max(textElement.width, columns[key])
- textElement.destroy()
- }
- }
- return columns
- }
MovieItem.qml
ListView のデリゲートです。list(main.qml) の columnWidths を使って、各列の幅を設定します。
- import Qt 4.7
- Component {
- Item {
- id: item
- width: parent.width - 15
- height: row.height
- function altColor(i) {
- var colors = [ "#bebebe", "#b7b7b7" ];
- return colors[i];
- }
- Rectangle {
- id: background
- width: parent.width + 15
- height: parent.height
- color: altColor(index%2)
- }
- Row {
- id: row
- width: parent.width
- spacing: 5
- Item {
- // Indent a little
- width: 5
- height: 1
- }
- Text {
- width: list.columnWidths['title']
- text: model.title
- color: "blue"
- }
- Loader { sourceComponent: columnSeparator; height: parent.height }
- Text {
- width: list.columnWidths['year']
- text: model.year
- }
- Loader { sourceComponent: columnSeparator; height: parent.height }
- Text {
- width: list.columnWidths['rank']
- text: model.rank
- }
- Loader { sourceComponent: columnSeparator; height: parent.height }
- Text {
- width: list.columnWidths['votes']
- text: model.votes
- }
- Loader { sourceComponent: columnSeparator; height: parent.height }
- Text {
- width: list.columnWidths['composer']
- text: model.composer ? model.composer : ""
- }
- Component {
- id: columnSeparator
- Rectangle {
- width: 1
- color: "black"
- opacity: 0.3
- }
- }
- }
- }
- }
MovieModel.qml
インターネット・ムービー・データベース( http://www.imdb.com )から取得した情報をモデルにしたものです。
- import Qt 4.7
- ListModel {
- ListElement {
- votes: 532564
- rank: 9.2
- title: "The Shawshank Redemption"
- year: 1994
- composer: "Newman, Thomas"
- }
- ListElement {
- votes: 419312
- rank: 9.1
- title: "The Godfather"
- year: 1972
- composer: "Rota, Nino"
- }
- ListElement {
- votes: 251290
- rank: 9.0
- title: "The Godfather: Part II"
- year: 1974
- composer: "Rota, Nino"
- }
- ListElement {
- votes: 225000
- rank: 8.9
- title: "Inception"
- year: 2010
- composer: "Zimmer, Hans"
- }
- ListElement {
- votes: 165033
- rank: 8.9
- title: "Il buono, il brutto, il cattivo."
- year: 1966
- composer: "Morricone, Ennio"
- }
- ListElement {
- votes: 426752
- rank: 8.9
- title: "Pulp Fiction"
- year: 1994
- }
- ListElement {
- votes: 282473
- rank: 8.9
- title: "Schindler's List"
- year: 1993
- composer: "Williams, John"
- }
- ListElement {
- votes: 122919
- rank: 8.9
- title: "12 Angry Men"
- year: 1957
- composer: "Hopkins, Kenyon"
- }
- ListElement {
- votes: 219739
- rank: 8.8
- title: "One Flew Over the Cuckoo's Nest"
- year: 1975
- composer: "Nitzsche, Jack"
- }
- ListElement {
- votes: 476112
- rank: 8.8
- title: "The Dark Knight"
- year: 2008
- composer: "Zimmer, Hans"
- }
- ListElement {
- votes: 283354
- rank: 8.8
- title: "Star Wars: Episode V - The Empire Strikes Back"
- year: 1980
- composer: "Williams, John"
- }
- ListElement {
- votes: 371790
- rank: 8.8
- title: "The Lord of the Rings: The Return of the King"
- year: 2003
- composer: "Shore, Howard"
- }
- ListElement {
- votes: 98799
- rank: 8.8
- title: "Shichinin no samurai"
- year: 1954
- composer: "Hayasaka, Fumio"
- }
- ListElement {
- votes: 326619
- rank: 8.7
- title: "Star Wars"
- year: 1977
- composer: "Williams, John"
- }
- ListElement {
- votes: 234582
- rank: 8.7
- title: "Goodfellas"
- year: 1990
- }
- ListElement {
- votes: 170874
- rank: 8.7
- title: "Casablanca"
- year: 1942
- composer: "Steiner, Max"
- }
- }

