第 5 课:Repeater、ListModel、ListView
更新: 10/23/2026 字数: 0 字 时长: 0 分钟
这一课分三步:
Repeater:重复生成元素ListModel:定义数据ListView:显示数据列表 + 委托(delegate)
使用 Repeater、ListModel 与 ListView 展示列表数据
1. Repeater:重复生成
上一课你已经见过 Repeater。它的作用是:根据 model 数量,重复生成子元素。
qml
import QtQuick
import QtQuick.Window
Window {
width: 320
height: 320
visible: true
Column {
anchors.centerIn: parent
spacing: 6
Repeater {
id: i
model: 5
Rectangle {
id: rect
required property int index
width: 200
height: 40
color: "lightblue"
Text {
anchors.centerIn: parent
text: "第 " + (parent.index + 1) + " 项"
}
}
}
}
}关键点:
model: 5表示重复 5 次。index是 Repeater 自动提供的当前序号,从 0 开始。- 每个
Rectangle是 Repeater 的子元素,被放进Column里排列。
Repeater 本身不显示任何东西,它只是“复制机”。
2. ListModel:结构化数据
model: 5 只能重复固定次数。真实场景里,数据通常是有字段的。用 ListModel:
qml
ListModel {
id: fruitModel
ListElement { name: "苹果"; price: 5 }
ListElement { name: "香蕉"; price: 3 }
ListElement { name: "橙子"; price: 4 }
}每个 ListElement 是一条数据,字段自定义。这里定义了 name 和 price。
3. ListView + delegate
ListView 是滚动列表视图,它需要一个 model 和一个 delegate。
delegate 是“每条数据怎么显示”的模板。
qml
import QtQuick
import QtQuick.Window
Window {
width: 320
height: 480
visible: true
title: "第五课"
ListModel {
id: fruitModel
ListElement { name: "苹果"; price: 5 }
ListElement { name: "香蕉"; price: 3 }
ListElement { name: "橙子"; price: 4 }
ListElement { name: "葡萄"; price: 8 }
ListElement { name: "西瓜"; price: 12 }
}
ListView {
anchors.fill: parent
model: fruitModel
spacing: 4
delegate: Rectangle {
required property string name
required property int price
width: ListView.view.width
height: 60
color: "lightyellow"
border.color: "gray"
Text {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 12
text: parent.name
font.pixelSize: 20
}
Text {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 12
text: parent.price + " 元"
font.pixelSize: 20
color: "tomato"
}
}
}
}运行后你会看到一个可滚动的列表,每行显示水果名和价格。
关键点讲解
1. delegate 里能直接访问模型字段
在 delegate 内部,可以直接写:
qml
text: name
text: price + " 元"不需要 fruitModel.get(index).name,QML 会自动把当前行的字段暴露给委托。
2. index 也能用
delegate 里还能用 index,表示当前行号,从 0 开始。
qml
text: (index + 1) + ". " + name3. ListView.view
在 delegate 里,ListView.view 指向所在的 ListView。
qml
width: ListView.view.width让每行宽度等于列表宽度,这是常见写法。
也可以用:
qml
width: parent.width但 parent 在委托里有时不一定是 ListView,所以推荐用 ListView.view.width。
4. spacing
ListView 的 spacing 控制行间距。
你的动手练习
练习 1
在 ListModel 里再加两条数据,观察列表是否能滚动。
练习 2
在 delegate 里加一行序号:
qml
text: (index + 1) + ". " + name练习 3
点击某一行时,在控制台打印它的名字。
提示:在 delegate 的 Rectangle 里加:
qml
MouseArea {
anchors.fill: parent
onClicked: console.log("点击了: " + name)
}练习 4
让奇数行和偶数行颜色不同:
qml
color: index % 2 === 0 ? "lightyellow" : "white"练习 5(思考题)
如果 delegate 里写:
qml
text: name但 ListModel 的字段叫 title,会发生什么?为什么?