QML学习十五:ListView的简单使用(内建Model)

转载QML学习十五:ListView的简单使用(内建Model)_qml listview-CSDN博客

一、概念

1、MVC

作为一种经典的架构模式,通过把职责、性质相近的成分归结在一起,不相近的进行隔离,MVC将系统分解为模型、视图、控制器三部分,每一部分都相对独立,职责单一。MVC是对系统复杂性的一种合理的梳理与切分,它的思想实质就是“关注点分离”。

QT中的Model-View编程框架,对Controller部分做了改动,引入了Delegate的概念,合起来就是Model-View-Delegate。

在QT C++中,对Model-View-Delegate已经做了基础的实现,不必去设计Model-View框架,只需学习Qt给的框架即可。

2、ListView

ListView用来一个条目列表,条目对应的数据来自于Model, 而每个条目的外观则由Delegate决定。

要使用ListView,必须指定一个Model、一个Delegate。

Model可以是QML内建类型,如ListModel、XmlListModel,也可以是在C++实现的QAbstractItemModel或QAbstractListModel的派生类。

二、ListView简单的使用

1、简单的显示例子

修改main.qml内容:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
 
import MyObj 1.0
 
 
Window {
    id: window
    visible: true
    width: 600
    height: 480
    title: qsTr("Hello World")
 
    Rectangle {
        width: 360
        height: 300
        color: "#EEEEEE"
 
        Component {
            id: phoneDelegate
 
            Item {
                id: wrapper
                width: parent.width
                height: 30
 
                MouseArea {
                    anchors.fill: parent
                    onClicked: wrapper.ListView.view.currentIndex = index
                }
 
                RowLayout {
                    anchors.left: parent.left
                    anchors.verticalCenter: parent.verticalCenter
                    spacing: 8
 
                    Text {
                        id: coll
                        text: name
                        color: wrapper.ListView.isCurrentItem ? "red" : "black"
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.preferredWidth: 120
                    }
 
                    Text {
                        text: cost
                        color: wrapper.ListView.isCurrentItem ? "red" : "black";
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.preferredWidth: 80
                    }
 
                    Text {
                        text: manufacturer
                        color: wrapper.ListView.isCurrentItem ? "red" : "black";
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.fillWidth: true
                    }
                }
            }
        }
 
        ListView {
            id: listView
            anchors.fill: parent
            delegate: phoneDelegate
 
            model: ListModel {
                id: phoneModel
 
                ListElement {
                    name: "iPhone 3gs"
                    cost: "1000"
                    manufacturer: "Apple"
                }
 
                ListElement {
                    name: "iphone 4"
                    cost: "1800"
                    manufacturer: "Apple"
                }
 
                ListElement {
                    name: "iphone 5"
                    cost: "2800"
                    manufacturer: "Apple"
                }
 
                ListElement {
                    name: "iphone 6"
                    cost: "3800"
                    manufacturer: "Apple"
                }
 
                ListElement {
                    name: "iphone 8"
                    cost: "4800"
                    manufacturer: "Apple"
                }
            }
            focus: true
            highlight: Rectangle {
                color: "lightblue"
            }
        }
    }
 
}
 
 
 

编译运行:

2、增加Head和Footer

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
 
import MyObj 1.0
 
 
Window {
    id: window
    visible: true
    width: 600
    height: 480
    title: qsTr("Hello World")
 
    Rectangle {
        width: 360
        height: 300
        color: "#EEEEEE"
 
        Component {
            id: phoneModel
 
            ListModel {
                ListElement {
                    name: "iPhone 3"
                    cost: "1000"
                    manufacturer: "Apple"
                }
                ListElement {
                    name: "iPhone 4"
                    cost: "2000"
                    manufacturer: "Apple"
                }
                ListElement {
                    name: "iPhone 5"
                    cost: "3000"
                    manufacturer: "Apple"
                }
                ListElement {
                    name: "iPhone 6"
                    cost: "4000"
                    manufacturer: "Apple"
                }
            }
        }
 
        Component {
            id: headerView
 
            Item {
                width: parent.width
 
                RowLayout {
                    anchors.left: parent.left
                    anchors.verticalCenter: parent.verticalCenter
                    spacing: 8
 
                    Text {
                        text: "Name"
                        font.bold: true
                        font.pixelSize: 20
                        Layout.preferredWidth: 120
                    }
 
                    Text {
                        text: "Cost"
                        font.bold: true
                        font.pixelSize: 20
                        Layout.preferredWidth: 80
                    }
 
                    Text {
                        text: "Manufacturer"
                        font.bold: true
                        font.pixelSize: 20
                        Layout.fillWidth: true
                    }
                }
            }
        }
 
        Component {
            id: footerView
 
            Text {
                width: parent.width
                font.italic: true
                color: "blue"
                height: 30
                verticalAlignment: Text.AlignVCenter
            }
        }
 
        Component {
            id: phoneDelegate
 
            Item {
                id: wrapper
 
                width: parent.width
                height: 30
 
                MouseArea {
                    anchors.fill: parent
                    onClicked: wrapper.ListView.view.currentIndex = index
                }
 
                RowLayout {
                    anchors.left: parent.left
                    anchors.verticalCenter: parent.verticalCenter
                    spacing: 8
 
                    Text {
                        id: coll
                        text: name
                        color: wrapper.ListView.isCurrentItem ? "red" : "black"
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.preferredWidth: 120
                    }
 
                    Text {
                        text: cost
                        color: wrapper.ListView.isCurrentItem ? "red" : "black";
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.preferredWidth: 80
                    }
 
                    Text {
                        text: manufacturer
                        color: wrapper.ListView.isCurrentItem ? "red" : "black";
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.fillWidth: true
                    }
                }
            }
        }
 
        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 = "-";
                }
            }
        }
    }
}
 
 
 

编译结果:

 3、访问与修改Model

(1) 访问数据

ListModel的count属性表示Model中有多少条数据。

ListModel的get()方法接受一个int类型的参数,用来获取指定索引位置的数据返回一个QML对象。

然后,我们就可以像访问属性那样访问数据的role。

eq:
 
var data = listView.model.get(listView.currentIndex);
console.log(data.name + "," + data.cost + "," + data.manufacturer);
(2) 删除数据

ListModel的remove(int index, int count)方法,删除一条或多条数据。

eq:
 
MouseArea {
    anchors.fill: parent
    onClicked: {
        wrapper.ListView.view.currentIndex = index;
    }
 
    onDoubleClicked: {
        wrapper.ListView.view.model.remove(index);
    }
}
 
(3) 修改数据

修改数据使用的是ListModel的setProperty(int index, string property, variant value)方法。

比如:修改价格
listView.model.setProperty(5, "cost", 16999)
(4) 添加数据

添加数据使用的是append()方法。

eq:
listView.model.append (
    {
        "name" : "mx3"
        "cost" : "1978"
        "manufacturer" : "Meizu"
    }
)

三、完整代码

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
 
import MyObj 1.0
 
 
Window {
    id: window
    visible: true
    width: 600
    height: 480
    title: qsTr("Hello World")
 
    Rectangle {
        width: 360
        height: 300
        color: "#EEEEEE"
 
        Component {
            id: phoneModel
 
            ListModel {
                ListElement {
                    name: "iPhone 3"
                    cost: "1000"
                    manufacturer: "Apple"
                }
                ListElement {
                    name: "iPhone 4"
                    cost: "2000"
                    manufacturer: "Apple"
                }
                ListElement {
                    name: "iPhone 5"
                    cost: "3000"
                    manufacturer: "Apple"
                }
                ListElement {
                    name: "iPhone 6"
                    cost: "4000"
                    manufacturer: "Apple"
                }
            }
        }
 
        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
                    }
 
                    Text {
                        text: "Cost"
                        font.bold: true
                        font.pixelSize: 20
                        Layout.preferredWidth: 80
                    }
 
                    Text {
                        text: "Manufacturer"
                        font.bold: true
                        font.pixelSize: 20
                        Layout.fillWidth: true
                    }
                }
            }
        }
 
        Component {
            id: footerView
 
            Item {
                id: footerRootItem
 
                width: parent.width
                height: 30
                property alias text: txt.text
                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
                }
 
                RowLayout {
                    anchors.left: parent.left
                    anchors.verticalCenter: parent.verticalCenter
                    spacing: 8
 
                    Text {
                        id: coll
                        text: name
                        color: wrapper.ListView.isCurrentItem ? "red" : "black"
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.preferredWidth: 120
                    }
 
                    Text {
                        text: cost
                        color: wrapper.ListView.isCurrentItem ? "red" : "black";
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.preferredWidth: 80
                    }
 
                    Text {
                        text: manufacturer
                        color: wrapper.ListView.isCurrentItem ? "red" : "black";
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.fillWidth: true
                    }
                }
            }
        }
 
        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 = "-";
                }
            }
 
            function addOne() {
                model.append(
                            {
                                "name" : "MX3",
                                "cost": "1233",
                                "manufacturer": "Meizu"
                            });
            }
 
            Component.onCompleted: {
                listView.footerItem.clean.connect(listView.model.clear);
                listView.footerItem.add.connect(listView.addOne);
            }
        }
    }
}
 
 
 

编译结果:

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值