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