English French [qt-devnet.developpez.com] 日本語 Български 한국어

How to create columns in a QML ListView

Here is one way to create a ListView with multiple columns whose widths depend upon the size of the data in the column.

Normally a ListView of Row elements would look like this.

ListView of Row elements

Columns can be created setting the widths in the Row elements.

ListView with columns

Getting the text width

Font metrics are not available in QML. However, Text elements can be created dynamically in JavaScript and queried for their width.

  1.     // Create temporary Text element
  2.     var textElement = Qt.createQmlObject('import Qt 4.7; Text { text: "' + text + '"}',
  3.                                          parent, "calcTextWidth");
  4.  
  5.     // Use textElement.width for the width of the text
  6.  
  7.     // Dispose of temporary element
  8.     textElement.destroy()

Creating columns in a ListView

The column widths are calculated for the model with JavaScript, stored in a map with keys by the model element names, and used in the ListView delegate.

main.qml

A simple UI to demonstrate the ListView. A Rectangle element is used as a container simply to give it a color consistent with the colors used for the rows. Note the columnWidths property is used to store the calculated widths, which are used in the delegate.

  1. import Qt 4.7
  2. import "ColumnHelper.js" as ColumnHelper
  3.  
  4. Rectangle {
  5.     width: 620
  6.     height: 200
  7.     color: "#bebebe"
  8.  
  9.     ListView {
  10.         id: list
  11.         property variant columnWidths: ColumnHelper.calcColumnWidths(model, list)
  12.         anchors.fill: parent
  13.         model: MovieModel { }
  14.         delegate:  MovieItem { }
  15.     }
  16.  
  17. }

ColumnHelper.js

A simple JavaScript function is used to find the maximum width for Text elements of all the data in every column and returns those values in an object keyed by the column name.

  1. var columns = {}
  2.  
  3. function calcColumnWidths(model, parent)
  4. {
  5.     for (var i = 0; i < model.count; ++i)
  6.     {
  7.         var data = model.get(i)
  8.         for (var key in data)
  9.         {
  10.             if (!columns[key]) {
  11.                 columns[key] = 0
  12.             }
  13.  
  14.             var textElement = Qt.createQmlObject(
  15.                     'import Qt 4.7;'
  16.                     + 'Text {'
  17.                     + '   text: "' + data[key] + '" '
  18.                     + '}',
  19.                     parent, "calcColumnWidths")
  20.  
  21.             columns[key] = Math.max(textElement.width, columns[key])
  22.             textElement.destroy()
  23.         }
  24.     }
  25.     return columns
  26. }

MovieItem.qml

This is the delegate for the ListView. The columnWidths property of the list is used to set the widths of the columns.

  1. import Qt 4.7
  2.  
  3. Component {
  4.     Item {
  5.         id: item
  6.         width: parent.width - 15
  7.         height: row.height
  8.  
  9.         function altColor(i) {
  10.             var colors = [ "#bebebe", "#b7b7b7" ];
  11.             return colors[i];
  12.         }
  13.  
  14.         Rectangle {
  15.             id: background
  16.             width:  parent.width + 15
  17.             height: parent.height
  18.             color: altColor(index%2)
  19.         }
  20.  
  21.         Row {
  22.             id: row
  23.             width: parent.width
  24.             spacing: 5
  25.             Item {
  26.                 // Indent a little
  27.                 width: 5
  28.                 height: 1
  29.             }
  30.             Text {
  31.                 width: list.columnWidths['title']
  32.                 text: model.title
  33.                 color: "blue"
  34.             }
  35.             Loader { sourceComponent: columnSeparator; height: parent.height }
  36.             Text {
  37.                 width: list.columnWidths['year']
  38.                 text: model.year
  39.             }
  40.             Loader { sourceComponent: columnSeparator; height: parent.height }
  41.             Text {
  42.                 width: list.columnWidths['rank']
  43.                 text: model.rank
  44.             }
  45.             Loader { sourceComponent: columnSeparator; height: parent.height }
  46.             Text {
  47.                 width: list.columnWidths['votes']
  48.                 text: model.votes
  49.             }
  50.             Loader { sourceComponent: columnSeparator; height: parent.height }
  51.             Text {
  52.                 width: list.columnWidths['composer']
  53.                 text: model.composer ? model.composer : ""
  54.             }
  55.  
  56.             Component {
  57.                 id: columnSeparator
  58.                 Rectangle {
  59.                     width: 1
  60.                     color: "black"
  61.                     opacity: 0.3
  62.                 }
  63.             }
  64.         }
  65.     }
  66. }

MovieModel.qml

Information courtesy of The Internet Movie Database (http://www.imdb.com).

  1. import Qt 4.7
  2.  
  3. ListModel {
  4.     ListElement {
  5.         votes: 532564
  6.         rank: 9.2
  7.         title: "The Shawshank Redemption"
  8.         year: 1994
  9.         composer: "Newman, Thomas"
  10.     }
  11.     ListElement {
  12.         votes: 419312
  13.         rank: 9.1
  14.         title: "The Godfather"
  15.         year: 1972
  16.         composer: "Rota, Nino"
  17.     }
  18.     ListElement {
  19.         votes: 251290
  20.         rank: 9.0
  21.         title: "The Godfather: Part II"
  22.         year: 1974
  23.         composer: "Rota, Nino"
  24.     }
  25.     ListElement {
  26.         votes: 225000
  27.         rank: 8.9
  28.         title: "Inception"
  29.         year: 2010
  30.         composer: "Zimmer, Hans"
  31.     }
  32.     ListElement {
  33.         votes: 165033
  34.         rank: 8.9
  35.         title: "Il buono, il brutto, il cattivo."
  36.         year: 1966
  37.         composer: "Morricone, Ennio"
  38.     }
  39.     ListElement {
  40.         votes: 426752
  41.         rank: 8.9
  42.         title: "Pulp Fiction"
  43.         year: 1994
  44.     }
  45.     ListElement {
  46.         votes: 282473
  47.         rank: 8.9
  48.         title: "Schindler's List"
  49.         year: 1993
  50.         composer: "Williams, John"
  51.     }
  52.     ListElement {
  53.         votes: 122919
  54.         rank: 8.9
  55.         title: "12 Angry Men"
  56.         year: 1957
  57.         composer: "Hopkins, Kenyon"
  58.     }
  59.     ListElement {
  60.         votes: 219739
  61.         rank: 8.8
  62.         title: "One Flew Over the Cuckoo's Nest"
  63.         year: 1975
  64.         composer: "Nitzsche, Jack"
  65.     }
  66.     ListElement {
  67.         votes: 476112
  68.         rank: 8.8
  69.         title: "The Dark Knight"
  70.         year: 2008
  71.         composer: "Zimmer, Hans"
  72.     }
  73.     ListElement {
  74.         votes: 283354
  75.         rank: 8.8
  76.         title: "Star Wars: Episode V - The Empire Strikes Back"
  77.         year: 1980
  78.         composer: "Williams, John"
  79.     }
  80.     ListElement {
  81.         votes: 371790
  82.         rank: 8.8
  83.         title: "The Lord of the Rings: The Return of the King"
  84.         year: 2003
  85.         composer: "Shore, Howard"
  86.     }
  87.     ListElement {
  88.         votes: 98799
  89.         rank: 8.8
  90.         title: "Shichinin no samurai"
  91.         year: 1954
  92.         composer: "Hayasaka, Fumio"
  93.     }
  94.     ListElement {
  95.         votes: 326619
  96.         rank: 8.7
  97.         title: "Star Wars"
  98.         year: 1977
  99.         composer: "Williams, John"
  100.     }
  101.     ListElement {
  102.         votes: 234582
  103.         rank: 8.7
  104.         title: "Goodfellas"
  105.         year: 1990
  106.     }
  107.     ListElement {
  108.         votes: 170874
  109.         rank: 8.7
  110.         title: "Casablanca"
  111.         year: 1942
  112.         composer: "Steiner, Max"
  113.     }
  114. }

Categories:

  • HowTo
  • Learning
  • snippets
  •