Qt Quick Examples - Views

This is a collection of QML model-view examples.

Views is a collection of small QML examples relating to model and view functionality. They demonstrate how to show data from a model using the Qt Quick view types. For more information, visit the Models and Views in Qt Quick page.

Running the Example

To run the example from Qt Creator, open the Welcome mode and select the example from Examples. For more information, visit Building and Running an Example.

Using GridView and PathView

GridView and PathView demonstrate usage of these types to display views.

     GridView {
         anchors.fill: parent
         cellWidth: 100
         cellHeight: 100
         focus: true
         model: appModel

         highlight: Rectangle {
             width: 80
             height: 80
             color: "lightsteelblue"
         }

         delegate: Item {
             required property string icon
             required property string name
             required property int index

             width: 100
             height: 100

             Image {
                 id: myIcon
                 y: 20
                 anchors.horizontalCenter: parent.horizontalCenter
                 source: parent.icon
             }
             Text {
                 anchors {
                     top: myIcon.bottom
                     horizontalCenter: parent.horizontalCenter
                 }
                 text: parent.name
             }
             MouseArea {
                 anchors.fill: parent
                 onClicked: parent.GridView.view.currentIndex = parent.index
             }
         }
     }

Using Dynamic List

Dynamic List demonstrates animation of runtime additions and removals to a ListView.

The ListView.onAdd signal handler runs an animation when new items are added to the view, and the ListView.onRemove another when they are removed.

         Item {
             SequentialAnimation {
                 id: addAnimation
                 PropertyAction {
                     target: delegateItem
                     property: "height"
                     value: 0
                 }
                 NumberAnimation {
                     target: delegateItem
                     property: "height"
                     to: 80
                     duration: 250
                     easing.type: Easing.InOutQuad
                 }
             }
             ListView.onAdd: addAnimation.start()

             SequentialAnimation {
                 id: removeAnimation
                 PropertyAction {
                     target: delegateItem
                     property: "ListView.delayRemove"
                     value: true
                 }
                 NumberAnimation {
                     target: delegateItem
                     property: "height"
                     to: 0
                     duration: 250
                     easing.type: Easing.InOutQuad
                 }

                 // Make sure delayRemove is set back to false so that the item can be destroyed
                 PropertyAction {
                     target: delegateItem
                     property: "ListView.delayRemove"
                     value: false
                 }
             }
             ListView.onRemove: removeAnimation.start()
         }
Expanding Delegates

Expanding Delegates demonstrates delegates that expand when activated.

It has a complex delegate the size and appearance of which can change, displacing other items in the view.

         Item {
             id: recipe

             required property string title
             required property string picture
             required property string ingredients
             required property string method

             // Create a property to contain the visibility of the details.
             // We can bind multiple element's opacity to this one property,
             // rather than having a "PropertyChanges" line for each element we
             // want to fade.
             property real detailsOpacity : 0
             MouseArea {
                 anchors.fill: parent
                 onClicked: recipe.state = 'Details';
             }

             // Lay out the page: picture, title and ingredients at the top, and method at the
             // bottom.  Note that elements that should not be visible in the list
             // mode have their opacity set to recipe.detailsOpacity.

             Row {
                 id: topLayout
                 x: 10
                 y: 10
                 height: recipeImage.height
                 width: parent.width
                 spacing: 10

                 Image {
                     id: recipeImage
                     width: 50
                     height: 50
                     source: recipe.picture
                 }
             Item {
                 id: details
                 x: 10
                 width: parent.width - 20

                 anchors {
                     top: topLayout.bottom
                     topMargin: 10
                     bottom: parent.bottom
                     bottomMargin: 10
                 }
                 opacity: recipe.detailsOpacity
             }

             // A button to close the detailed view, i.e. set the state back to default ('').
             TextButton {
                 y: 10
                 anchors {
                     right: background.right
                     rightMargin: 10
                 }
                 opacity: recipe.detailsOpacity
                 text: qsTr("Close")

                 onClicked: recipe.state = '';
             }

             states: State {
                 name: "Details"

                 PropertyChanges {
                     background.color: "white"
                     recipeImage {
                          // Make picture bigger
                         width: 130
                         height: 130
                     }
                     recipe {
                         // Make details visible
                         detailsOpacity: 1
                         x: 0

                         // Fill the entire list area with the detailed view
                         height: listView.height
                     }
                 }

                 // Move the list so that this item is at the top.
                 PropertyChanges {
                     recipe.ListView.view.contentY: recipe.y
                     explicit: true;
                 }

                 // Disallow flicking while we're in detailed view
                 PropertyChanges {
                     recipe.ListView.view.interactive: false
                 }
             }

             transitions: Transition {
                 // Make the state changes smooth
                 ParallelAnimation {
                     ColorAnimation {
                         property: "color"
                         duration: 500
                     }
                     NumberAnimation {
                         duration: 300
                         properties: "detailsOpacity,x,contentY,height,width"
                     }
                 }
             }
         }

Using Highlight

Highlight demonstrates adding a custom highlight to a ListView.

     // Define a highlight with customized movement between items.
     component HighlightBar : Rectangle {
         width: 200
         height: 50
         color: "#FFFF88"
         y: ListView.view.currentItem.y
         Behavior on y {
             SpringAnimation {
                 spring: 2
                 damping: 0.1
             }
         }
     }

     ListView {
         id: listView
         width: 200
         height: parent.height
         x: 30

         model: PetsModel { }
         delegate: PetDelegate { }
         focus: true

         // Set the highlight delegate. Note we must also set highlightFollowsCurrentItem
         // to false so the highlight delegate can control how the highlight is moved.
         highlight: HighlightBar { }
         highlightFollowsCurrentItem: false
     }

Using Highlight Ranges

Highlight Ranges shows the three different highlight range modes of ListView.

 Rectangle {
     id: root
     property int current: 0
     property bool increasing: true
     // Example index automation for convenience, disabled on click or tap
     SequentialAnimation {
         id: anim
         loops: -1
         running: true
         ScriptAction {
             script: if (root.increasing) {
                         root.current++;
                         if (root.current >= aModel.count -1) {
                             root.current = aModel.count - 1;
                             root.increasing = !root.increasing;
                         }
                     } else {
                         root.current--;
                         if (root.current <= 0) {
                             root.current = 0;
                             root.increasing = !root.increasing;
                         }
                     }
         }

         PauseAnimation {
             duration: 500
         }
     }
     ListView {
         id: list1
         height: 50
         width: parent.width
         model: PetsModel {
             id: aModel
         }
         delegate: petDelegate
         orientation: ListView.Horizontal
         highlight: Rectangle {
             color: "lightsteelblue"
         }
         currentIndex: root.current
         onCurrentIndexChanged: root.current = currentIndex
         focus: true
     }

     ListView {
         id: list2
         y: 160
         height: 50
         width: parent.width
         model: PetsModel { }
         delegate: petDelegate
         orientation: ListView.Horizontal
         highlight: Rectangle {
             color: "yellow"
         }
         currentIndex: root.current
         preferredHighlightBegin: 80
         preferredHighlightEnd: 220
         highlightRangeMode: ListView.ApplyRange
     }

     ListView {
         id: list3
         y: 320
         height: 50
         width: parent.width
         model: PetsModel {}
         delegate: petDelegate
         orientation: ListView.Horizontal
         highlight: Rectangle { color: "yellow" }
         currentIndex: root.current
         onCurrentIndexChanged: root.current = currentIndex
         preferredHighlightBegin: 125
         preferredHighlightEnd: 125
         highlightRangeMode: ListView.StrictlyEnforceRange
     }
 }

Using Sections

Sections demonstrates the various section headers and footers available to ListView.

     // The delegate for each section header
     Component {
         id: sectionHeading
         Rectangle {
             width: ListView.view.width
             height: childrenRect.height
             color: "lightsteelblue"

             required property string section

             Text {
                 text: parent.section
                 font.bold: true
                 font.pixelSize: 20
             }
         }
     }

     ListView {
         id: view
         anchors.top: parent.top
         anchors.bottom: buttonBar.top
         width: parent.width
         model: animalsModel
         delegate: Text {
             required property string name

             text: name
             font.pixelSize: 18
         }

         section.property: "size"
         section.criteria: ViewSection.FullString
         section.delegate: sectionHeading
     }

Using Packages

Packages uses the Package type to transition delegates between two views.

It has a Package object which defines delegate items for each view and an item that can be transferred between delegates.

 Package {
     id: delegate

     required property int upTo
     required property int index
     required property string display

     Text {
         id: listDelegate
         width: parent.width
         height: 25
         text: 'Empty'
         Package.name: 'list'
     }

     Text {
         id: gridDelegate
         width: parent.width / 2
         height: 50
         text: 'Empty'
         Package.name: 'grid'
     }

     Rectangle {
         id: wrapper
         width: parent?.width ?? 0
         height: 25
         color: 'lightsteelblue'

         Text {
             text: delegate.display
             anchors.centerIn: parent
         }
         state: delegate.upTo > delegate.index ? 'inGrid' : 'inList'
         states: [
             State {
                 name: 'inList'
                 ParentChange {
                     target: wrapper
                     parent: listDelegate
                 }
             },
             State {
                 name: 'inGrid'
                 ParentChange {
                     target: wrapper
                     parent: gridDelegate
                     x: 0
                     y: 0
                     width: gridDelegate.width
                     height: gridDelegate.height
                 }
             }
         ]

         transitions: [
             Transition {
                 ParentAnimation {
                     NumberAnimation {
                         properties: 'x,y,width,height'
                         duration: 300
                     }
                 }
             }
         ]
     }
 }

A DelegateModel allows the individual views to access their specific items from the shared package delegate.

 DelegateModel {
     id: visualModel
     delegate: Delegate {
         upTo: root.upTo
     }
     model: myModel
 }

 ListView {
     id: lv
     height: parent.height / 2
     width: parent.width

     model: visualModel.parts.list
 }
 GridView {
     y: parent.height / 2
     height: parent.height / 2
     width: parent.width
     cellWidth: width / 2
     cellHeight: 50
     model: visualModel.parts.grid
 }

Draggable Selections demonstrates the use of Package to group together multiple selected delegates for drag-and-drop within an item view.

         Package {
             id: packageRoot

             required property var modelData

             MouseArea {
                 id: visibleContainer
                 Package.name: "visible"

                 width: 64
                 height: 64
                 enabled: packageRoot.DelegateModel.inSelected

                 drag.target: draggable

                 Item {
                     id: draggable

                     Drag.active: visibleContainer.drag.active

Using ObjectModel

ObjectModel uses an ObjectModel for the model instead of a ListModel.

     ObjectModel {
         id: itemModel

         Rectangle {
             width: view.width
             height: view.height
             color: "#FFFEF0"

             Text {
                 anchors.centerIn: parent
                 text: qsTr("Page 1")
                 font.bold: true
             }

             Component.onDestruction: if (root.printDestruction) print("destroyed 1")
         }
         Rectangle {
             width: view.width
             height: view.height
             color: "#F0FFF7"

             Text {
                 anchors.centerIn: parent
                 text: qsTr("Page 2")
                 font.bold: true
             }

             Component.onDestruction: if (root.printDestruction) print("destroyed 2")
         }
         Rectangle {
             width: view.width
             height: view.height
             color: "#F4F0FF"

             Text {
                 anchors.centerIn: parent
                 text: qsTr("Page 3")
                 font.bold: true
             }

             Component.onDestruction: if (root.printDestruction) print("destroyed 3")
         }
     }

     ListView {
         id: view
         anchors {
             fill: parent
             bottomMargin: 30
         }
         model: itemModel
         preferredHighlightBegin: 0
         preferredHighlightEnd: 0
         highlightRangeMode: ListView.StrictlyEnforceRange
         orientation: ListView.Horizontal
         snapMode: ListView.SnapOneItem
         flickDeceleration: 2000
         cacheBuffer: 200
     }

Using Display Margins

Display Margins uses delegates to display items and implements a simple header and footer components.

Example project @ code.qt.io