How to create columns in a QML ListView/ja

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

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"
 }
}