使用 ListView 是為了向使用者展示某些資料,期望使用者根據這些資料做出一些回報,比如買某個東西。而我們會經常需要通路、修改一個 ListView 展現的資料。現在我們就來看看怎麼做。
1、通路資料
ListModel 的 count 屬性表示 Model 中有多少條資料,int 類型。dynamicRoles 屬性為布爾值,為 true 時表示 Model 中的 role 對應的值的類型可以動态改變,預設值是 false。要設定 dynamicRoles,必須在添加資料之前。不過要注意的是,一旦你使能了 dynamicRoles,ListModel 的性能會大大下降,通常它帶來的性能損失是使用靜态類型的 4〜6 倍。
ListModel 的get()方法接受一個 int 類型的參數,用來擷取指定索引位置的資料,傳回一 個 QML 對象。然後,我們就可以像通路屬性那樣通路資料的 role 了,正如我們在前面使用的那樣:
var data = listView.model.get(listView.currentIndex}
listView.footerltem.text = data.name + " , " + data.cost + " , " + data.manufacturer
2、删除資料
如果你想删除一條或多條資料,可以使用 ListModel 的remove(int index, int count)方法,它有兩個整型參數,第一個參數指明要删除的資料的索引位置,第二個參數表示要删除的資料條數,預設值為 1。
如果你想清空一個 Model,可以直接調用 clear() 方法。
現在我們将 phone_list_footer.qml 另存為 phone_list_change.qml,将 phoneDelegate 内的 MouseArea 對象修改為下面的樣子:
MouseArea {
anchors.fill: parent
onClicked: {
wrapper.ListView.view.currentlndex = index
}
onDoubleClicked: {
wrapper.ListView.view.model.remove(index)
}
}
然後執行 “qmlscene phone_list_change.qml” 指令,用滑鼠左鍵輕按兩下某個 Item,該 Item 就會從 ListView 中删除。
讓我們再修改一下 footer 元件,添加一個清除按鈕,用來清除所有的資料。footer 元件的新代碼如下:
Component {
id: footerView
Item{
id: footerRootItem
width: parent.width
height: 30
property alias text: txt.text
signal clean()
Text {
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
id: txt
font.italic: true
color: "blue"
verticalAlignment: Text.AlignVCenter
}
Button {
id: clearAll
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: "Clear"
onClicked: footerRootItem.clean()
}
}
}
給 ListView 添加 Component.onCompleted 附加信号處理器:
Component.onCompleted: {
listView.footerItem.clean.connect(listView.model.clear)
}
現在可以運作 phone_list_change.qml 了,看到界面右下角的 “Clear” 按鈕了吧,點選它,清單所有資料就沒啦。
3、修改資料
要想修改 Model 的資料,可以使用 ListModel 的setProperty(int index,string property, variant value)方法。該方法有三個參數,第一個是資料的索引,第二個是資料内 role 的名字,第三個是mle的值。比如要修改 “MI 2S" 的價格,可以這樣:
listView.model.setProperty(5, "cost", 16999)
如果想替換某一條資料,可以使用set(int index, jsobject dict)方法。我們經常用對象的字面量表示法構造一個對象傳遞給 set() 方法。比如想把 “iPhone 3GS” 替換為 “Z5S mini”,可以這樣:
listView.model.set(0, {"name" : "25S mini ", "cost" : 1999, "manufacturer" : "ZhongXing"})
4、添加資料
要向 Model 的尾部添加資料,可以使用append()方法。append() 的參數是 jsobject,在 ECMAScript 中可以使用對象的字面量表示法來構造這個 jsobject,即花括号加 key-value 對的 集合,類似于這樣:{"name" : "zhangsan", "age" : 28},key-value 對之間使用逗号分隔。這種方式與 QML 對象聲明的方式略有不同。給個簡單的例子:
function addOne(){
model.append(
{
"name": "MX3",
"cost": "1799",
"manufacturer": "MeiZu"
}
);
}
如果想在指定位置添加資料,可以使用insert()方法,它的第一個參數是整型的,代表插 入的索引位置,第二個參數是 jsobject。
QT開發交流+赀料君羊:714620761
再來修改下phone_list_change.qml,新增添加資料的代碼,全新的内容如下:
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
Rectangle {
width: 360
height: 300
color: "#EEEEEE"
Component {
id: headerView
Item {
width: parent.width
height: 30
RowLayout {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
spacing: 8
Text {
text: "Name"
font.bold: true
font.pixelSize: 20
Layout.preferredWidth: 120
}
// 省略。。。
}
}
}
Component {
id: footerView
Item{
id: footerRootItem
width: parent.width
height: 30
property alias text: txt.text
// 1.自定義信号
signal clean()
signal add()
Text {
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
id: txt
font.italic: true
color: "blue"
verticalAlignment: Text.AlignVCenter
}
Button {
id: clearAll
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: "Clear"
onClicked: footerRootItem.clean()
}
Button {
id: addOne
anchors.right: clearAll.left
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter
text: "Add"
onClicked: footerRootItem.add()
}
}
}
Component {
id: phoneDelegate
Item {
id: wrapper
width: parent.width
height: 30
MouseArea {
anchors.fill: parent
onClicked: {
wrapper.ListView.view.currentIndex = index
mouse.accepted = true
}
onDoubleClicked: {
wrapper.ListView.view.model.remove(index)
mouse.accepted = true
}
}
RowLayout {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
spacing: 8
Text {
id: col1
text: name
color: wrapper.ListView.isCurrentItem ? "red" : "black"
font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
Layout.preferredWidth: 120
}
// 省略。。。
}
}
}
Component {
id: phoneModel;
ListModel {
ListElement{
name: "iPhone 3GS"
cost: "1000"
manufacturer: "Apple"
}
// 省略。。。
}
}
ListView {
id: listView
anchors.fill: parent
delegate: phoneDelegate
model: phoneModel.createObject(listView)
header: headerView
footer: footerView
focus: true
highlight: Rectangle{
color: "lightblue"
}
onCurrentIndexChanged: {
if( listView.currentIndex >=0 ){
var data = listView.model.get(listView.currentIndex)
listView.footerItem.text = data.name + " , " + data.cost + " , " + data.manufacturer
}else{
listView.footerItem.text = ""
}
}
// 2.槽函數:添加資料
function addOne() {
model.append(
{
"name": "MX3",
"cost": "1799",
"manufacturer": "MeiZu"
}
)
}
// 3.連接配接信号槽
Component.onCompleted: {
listView.footerItem.clean.connect(listView.model.clear)
listView.footerItem.add.connect(listView.addOne)
}
}
}
執行 “qmlscenephone_list_change.qml" 指令後的初始效果如下圖所示。
點選 "Add" 按鈕後的效果如下圖所示。
到現在為止,這個例子涵蓋了 ListView 的基本應用,包括怎樣初始化一個 ListView、通路資料、删除資料、動态添加資料、處理高亮等内容。你可以點選 “Clear” 按鈕、點選某個 Item 或者輕按兩下某個 Item 看看效果。