// 04-listview/listview.qml // ListView: scrollable list with a ListModel (observable). // Pure QML. Run with: qml6 listview.qml import QtQuick import QtQuick.Window import QtQuick.Controls Window { width: 360 height: 400 visible: true title: "QML 04: ListView" ListModel { id: tasks ListElement { title: "Ship the QML skill"; done: true } ListElement { title: "Validate with prototypes"; done: true } ListElement { title: "Add component examples"; done: false } ListElement { title: "Write reference docs"; done: false } } Column { anchors.fill: parent anchors.margins: 12 spacing: 8 // Header Row { spacing: 8 Button { text: "Add" onClicked: tasks.append({ title: "New task " + (tasks.count + 1), done: false }) } Button { text: "Clear done" onClicked: { for (let i = tasks.count - 1; i >= 0; i--) { if (tasks.get(i).done) tasks.remove(i) } } } } // The list ListView { width: parent.width height: parent.height - y clip: true spacing: 4 model: tasks delegate: Rectangle { required property var modelData required property int index width: ListView.view.width implicitHeight: 44 radius: 4 color: modelData.done ? "#e8f5e9" : "white" border.color: "#ccc" border.width: 1 Row { anchors.fill: parent anchors.leftMargin: 12 anchors.rightMargin: 12 spacing: 8 CheckBox { anchors.verticalCenter: parent.verticalCenter checked: modelData.done Accessible.name: "Completed: " + modelData.title onToggled: tasks.setProperty(index, "done", checked) } Text { anchors.verticalCenter: parent.verticalCenter text: modelData.title font.strikeout: modelData.done color: modelData.done ? "#888" : "black" } } // Click row to delete TapHandler { acceptedButtons: Qt.RightButton onTapped: tasks.remove(index) } } // Empty state Text { anchors.centerIn: parent visible: tasks.count === 0 text: "No tasks. Click Add to start." color: "#999" } } } }