Qt Quick Examples - Views | Qt Quick (original) (raw)

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, see Qt Creator: Tutorial: Build and run.

Using GridView and PathView

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

[GridView](qml-qtquick-gridview.html) {
    anchors.fill: parent
    cellWidth: 100
    cellHeight: 100
    focus: true
    model: appModel

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

    delegate: Item {
        required property [string](qml-string.html) icon
        required property [string](qml-string.html) name
        required property [int](qml-int.html) index

        width: 100
        height: 100

        [Image](qml-qtquick-image.html) {
            id: myIcon
            y: 20
            anchors.horizontalCenter: parent.horizontalCenter
            source: parent.icon
        }
        [Text](qml-qtquick-text.html) {
            anchors {
                top: myIcon.bottom
                horizontalCenter: parent.horizontalCenter
            }
            text: parent.name
        }
        [MouseArea](qml-qtquick-mousearea.html) {
            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](qml-qtquick-item.html) {
        [SequentialAnimation](qml-qtquick-sequentialanimation.html) {
            id: addAnimation
            [PropertyAction](qml-qtquick-propertyaction.html) {
                target: delegateItem
                property: "height"
                value: 0
            }
            [NumberAnimation](qml-qtquick-numberanimation.html) {
                target: delegateItem
                property: "height"
                to: 80
                duration: 250
                easing.type: Easing.InOutQuad
            }
        }
        ListView.onAdd: addAnimation.start()

        [SequentialAnimation](qml-qtquick-sequentialanimation.html) {
            id: removeAnimation
            [PropertyAction](qml-qtquick-propertyaction.html) {
                target: delegateItem
                property: "ListView.delayRemove"
                value: true
            }
            [NumberAnimation](qml-qtquick-numberanimation.html) {
                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](qml-qtquick-propertyaction.html) {
                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](qml-qtquick-item.html) {
        id: recipe

        required property [string](qml-string.html) title
        required property [string](qml-string.html) picture
        required property [string](qml-string.html) ingredients
        required property [string](qml-string.html) 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](qml-real.html) detailsOpacity : 0
        [MouseArea](qml-qtquick-mousearea.html) {
            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](qml-qtquick-row.html) {
            id: topLayout
            x: 10
            y: 10
            height: recipeImage.height
            width: parent.width
            spacing: 10

            [Image](qml-qtquick-image.html) {
                id: recipeImage
                width: 50
                height: 50
                source: recipe.picture
            }
        [Item](qml-qtquick-item.html) {
            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](qml-qtquick-propertychanges.html) {
                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](qml-qtquick-propertychanges.html) {
                recipe.ListView.view.contentY: recipe.y
                explicit: true;
            }

            // Disallow flicking while we're in detailed view
            [PropertyChanges](qml-qtquick-propertychanges.html) {
                recipe.ListView.view.interactive: false
            }
        }

        transitions: Transition {
            // Make the state changes smooth
            [ParallelAnimation](qml-qtquick-parallelanimation.html) {
                [ColorAnimation](qml-qtquick-coloranimation.html) {
                    property: "color"
                    duration: 500
                }
                [NumberAnimation](qml-qtquick-numberanimation.html) {
                    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](qml-qtquick-rectangle.html) {
    width: 200
    height: 50
    color: "#FFFF88"
    y: ListView.view.currentItem.y
    Behavior on y {
        [SpringAnimation](qml-qtquick-springanimation.html) {
            spring: 2
            damping: 0.1
        }
    }
}

[ListView](qml-qtquick-listview.html) {
    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](qml-qtquick-pauseanimation.html) {
        duration: 500
    }
}
[ListView](qml-qtquick-listview.html) {
    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](qml-qtquick-listview.html) {
    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](qml-qtquick-listview.html) {
    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](qml-qtquick-rectangle.html) {
        width: ListView.view.width
        height: childrenRect.height
        color: "lightsteelblue"

        required property [string](qml-string.html) section

        [Text](qml-qtquick-text.html) {
            text: parent.section
            font.bold: true
            font.pixelSize: 20
        }
    }
}

[ListView](qml-qtquick-listview.html) {
    id: view
    anchors.top: parent.top
    anchors.bottom: buttonBar.top
    width: parent.width
    model: animalsModel
    delegate: Text {
        required property [string](qml-string.html) 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](qml-int.html) upTo
required property [int](qml-int.html) index
required property [string](qml-string.html) display

[Text](qml-qtquick-text.html) {
    id: listDelegate
    width: parent.width
    height: 25
    text: 'Empty'
    Package.name: 'list'
}

[Text](qml-qtquick-text.html) {
    id: gridDelegate
    width: parent.width / 2
    height: 50
    text: 'Empty'
    Package.name: 'grid'
}

[Rectangle](qml-qtquick-rectangle.html) {
    id: wrapper
    width: parent?.width ?? 0
    height: 25
    color: 'lightsteelblue'

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

    transitions: [
        [Transition](qml-qtquick-transition.html) {
            [ParentAnimation](qml-qtquick-parentanimation.html) {
                [NumberAnimation](qml-qtquick-numberanimation.html) {
                    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](qml-qtqml-models-package.html) {
        id: packageRoot

        required property [var](qml-var.html) modelData

        [MouseArea](qml-qtquick-mousearea.html) {
            id: visibleContainer
            Package.name: "visible"

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

            drag.target: draggable

            [Item](qml-qtquick-item.html) {
                id: draggable

                Drag.active: visibleContainer.drag.active

Using ObjectModel

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

[ObjectModel](qml-qtqml-models-objectmodel.html) {
    id: itemModel

    [Rectangle](qml-qtquick-rectangle.html) {
        width: view.width
        height: view.height
        color: "#FFFEF0"

        [Text](qml-qtquick-text.html) {
            anchors.centerIn: parent
            text: qsTr("Page 1")
            font.bold: true
        }

        Component.onDestruction: if (root.printDestruction) print("destroyed 1")
    }
    [Rectangle](qml-qtquick-rectangle.html) {
        width: view.width
        height: view.height
        color: "#F0FFF7"

        [Text](qml-qtquick-text.html) {
            anchors.centerIn: parent
            text: qsTr("Page 2")
            font.bold: true
        }

        Component.onDestruction: if (root.printDestruction) print("destroyed 2")
    }
    [Rectangle](qml-qtquick-rectangle.html) {
        width: view.width
        height: view.height
        color: "#F4F0FF"

        [Text](qml-qtquick-text.html) {
            anchors.centerIn: parent
            text: qsTr("Page 3")
            font.bold: true
        }

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

[ListView](qml-qtquick-listview.html) {
    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