Model
-
ListModel 是QML中用于存储列表数据的模型类型。它允许您定义一组数据项,每个数据项由一组键值对组成。
-
id: contactsModel 为这个
ListModel
实例设置了一个ID,以便在QML的其他部分引用它。 -
ListElement 是
ListModel
中定义数据项的方式。每个ListElement
包含一组键值对,这些键值对定义了数据项的属性。 -
数据部分(Model),放在C++或者QML中,用于存储上面的三个属性。可能是以一个数据类(Dataltem/Object)和一个数据容器(QList/Array)的形式存在
Component
-
Component.onCompleted 是一个信号处理程序,它在组件完成加载并初始化后立即触发。
-
startAddingContacts() 是
ListModel
中定义的一个函数,用于开始一个定时器,该定时器每秒向模型中添加一个新的联系人。
Timer
-
Timer 是QML中的一个元素,用于创建定时器。
-
interval 设置定时器触发的间隔时间(以毫秒为单位)。
-
running 设置为
true
,使得定时器在创建后立即开始运行。 -
repeat 设置为
true
,使得定时器重复触发。 -
onTriggered 是定时器触发时执行的代码块。
ListView
-
ListView 是QML中的一个元素,用于显示基于模型的列表数据。
-
anchors.fill: parent 使
ListView
填充其父元素(在这个例子中是Window
)。 -
clip 设置为
true
,使得超出ListView
边界的内容不可见。 -
spacing 设置列表项之间的间距。
-
model 指定
ListView
使用的数据模型(在这个例子中是contactsModel
)。 -
delegate 定义如何显示列表中的每个数据项。在这个例子中,每个数据项都被显示为一个包含多个
Text
元素的RowLayout
。 -
界面部分(View):放置在QML代码中,用于构建出单个项目的显示内容排布,可能是以一个RowLayout的形式存在
Delegate
- 委托部分(Detegate):放在QML代码中,用于对数据容器中的项目进行迭代,为每个迭代项目分配数据
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Window {//window是根目录
width: 640//设置窗口参数
height: 480
visible: true
title: qsTr("Call Me Daddy")
id: rootWindow//程序里面可以不用这个,没用到,一般设置id是方便后面程序中引用
ListModel {//一个模型类型节点,包含数据项,数据项包含键值对
id: contactsModel//方便后面引用
ListElement { name: "Alice"; number: "555-1234"; address: "123 Main Street" }
ListElement { name: "Bob"; number: "555-5678"; address: "123 Main Street" }
ListElement { name: "Charlie"; number: "555-9999"; address: "123 Main Street" }
Component.onCompleted: {
startAddingContacts();
}
function startAddingContacts() {//是在一个定时器触发时,不断向一个名为 contactsModel 的模型中添加新的联系人信息。
var timer = Qt.createTimer();
timer.interval = 1000;
timer.repeat = true;
//连接触发信号到处理函数:
timer.triggered.connect(function() {//处理内容
var newName = "New Contact" + Math.floor(Math.random() * 1000);
var newNumber = "555-" + Math.floor(Math.random() * 10000);
contactsModel.append({ name: newName, number: newNumber, address: "123 Main Street" });
console.log("Timer triggered! New contact added: " + newName);
});
timer.start();
}
}
Timer {
interval: 1000; running: true; repeat: true
onTriggered: {
//Math.random() * 1000 生成一个 0(包括)到 1000(不包括)之间的随机浮点数。Math.floor(...) 将这个随机浮点数向下取整到最接近的整数,得到一个 0 到 999 之间的随机整数。"New Contact" + ... 将这个随机整数(此时它仍然是一个数值类型)与字符串 "New Contact" 进行拼接。由于加号运算符的一个操作数是字符串,JavaScript 会自动将另一个操作数(即随机整数)转换为字符串。拼接后的结果是一个新的字符串,它被赋值给变量 newName。
// 向contactsModel中添加一个新元素
//var newName =Math.floor(Math.random() * 1000)
var newName = "New Contact" + Math.floor(Math.random() * 1000)
var newNumber = "555-" + Math.floor(Math.random() * 10000)
contactsModel.append({ name: newName, number: newNumber, address: "123 Main Street" })
// 通常情况下,ListModel会自动通知视图更新,因此不需要手动调用contactsModelChanged()
// 但如果您需要在模型更改时执行其他操作,可以在这里添加代码
console.log("定时器触发!添加了新联系人:" + newName)
}
}
ListView {
anchors.fill: parent
clip: true
spacing: 5
model: contactsModel
delegate: Item {
width: parent.width
height: 30
RowLayout {
spacing: 5
Text {
text: model.name
}
Text {
text: "|"
}
Text {
text: model.number
}
Text {
text: "|"
}
Text {
text: model.address
}
// 最后一个 "|" 可能是不必要的,除非您有特定的设计需求
// 如果不需要,可以移除上面的 Text { text: "|" } 和这个
}
}
}
}
-
使用了
ListModel
和ListElement
来定义模型。 -
创建了一个定时器,它在组件完成时开始,并在每次触发时向模型添加一个新元素。
-
移除了对不存在的
contactsModelChanged()
方法的调用。 -
将
delegate
设置为一个Item
,其中包含一个RowLayout
和用于显示数据的Text
组件。 -
我修正了
title
属性中的文本。
请注意,由于 ListModel
的限制,您不能直接在模型元素中使用 JavaScript 表达式(如随机数生成)。因此,我在定时器触发时生成新数据,并使用 append()
方法将其添加到模型中。这种方法是可行的,但如果您需要更复杂的模型行为,您可能需要实现一个自定义的 C++ 模型类。
经过我不懈的努力,终于可以很好的显示了
请多多指教