How to create columns in a QML ListView/ja

From Qt Wiki
Jump to: navigation, search

En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh

QML の ListView で列(Column)を作る方法

その列のデータの幅に応じたサイズの複数の列を、DOC:ListView に作る方法の一つを説明します。

通常、ListView 内の DOC:Row 要素は以下のように表示されます。

ListView of Row elements

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

ListView with columns

文字列の幅の取得

QML にはフォントメトリックスはありません。しかし、JavaScript で DOC:Text 要素を動的に生成することで、文字列の幅を取得することができます。

// 一時的な Text 要素を作成
var textElement = Qt.createQmlObject('import Qt 4.7; Text { text: "' + text + '"}',
parent, "calcTextWidth");

// textElement.width で文字列(text)の幅を取得

// 一時要素を破棄

textElement.destroy()

ListView に列を作る

列の幅は JavaScript でモデルから計算し、モデルの要素名を鍵としてマップに保存します。ListView のデリゲート(delegate)でその幅を用います。

main.qml

ListView のデモ用の簡単な UI です。DOC: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
}
var textElement = Qt.createQmlObject(
'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"
}

}