zoukankan      html  css  js  c++  java
  • qml----Model/View入门(一)listview

    在SmallTalk中有一个经典的设计模式-MVC。即模型-视图-控制器,在qml中将control改成了delegate(委托),也就是现在的Model-View-Delegate.换了个说法,Model还是负责数据,View管着视图输出,Delegate呢就是一个介于视图和数据之间的桥梁。

    下面先来看个例子,效果图如下:

    import QtQuick 2.2
    import QtQuick.Controls 1.1
    import QtQuick.Layouts 1.1
    
    Rectangle{
         360
        height: 300
        color: "#EEEEEE"
    
        Component{
            id: phoneModel
    
            ListModel{
                ListElement{
                    name: "iphone 3GS"
                    cost: "1000"
                    manufacturer: "Apple"
                }
    
                ListElement{
                    name: "iphone 4"
                    cost: "1800"
                    manufacturer: "Apple"
                }
    
                ListElement{
                    name: "iphone 4s"
                    cost: "2300"
                    manufacturer: "Apple"
                }
    
                ListElement{
                    name: "iphne 5"
                    cost: "1590"
                    manufacturer: "Apple"
                }
    
                ListElement{
                    name: "iphone B199"
                    cost: "1590"
                    manufacturer: "HuaWei"
                }
    
                ListElement{
                    name: "MI 25"
                    cost: "1999"
                    manufacturer: "XiaoMi"
                }
    
                ListElement{
                    name: "GALAXY s5"
                    cost: "4698"
                    manufacturer: "Samsung"
                }
            }
        }//phoneModel is end(视图数据)
    
        Component{
            id: headView
            Item {
                 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
                    }
                }
            }
        }//headview is end(定义的表头)
    
        Component{
            id: footerView
    
            Item{
                id: footerRootItem
                 parent.width
                height: 30
                property alias text: txt.text
                signal clean()
                signal change()
                signal replace()
    
                Text{
                    id: txt
                    anchors.left: parent.left
                    anchors.top: parent.top
                    anchors.bottom: parent.bottom
                     parent.width/4
                    font.italic: true
                    color: "blue"
                    verticalAlignment: Text.AlignVCenter
                }
    
                Button{
                    id: cleanBtn
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                    text: "clear"
                    onClicked: footerRootItem.clean()
                }//清空视图数据的按钮
    
                Button{
                    id: changeBtn
                    anchors.right: cleanBtn.left
                    anchors.rightMargin:  5
                    anchors.verticalCenter: parent.verticalCenter
                    text: "change data"
                    onClicked: footerRootItem.change()
                }//改变选中行数据
    
                Button{
                    id: replaceBtn
                    anchors.right: changeBtn.left
                    anchors.rightMargin: 5
                    anchors.verticalCenter: parent.verticalCenter
                    text: "replace data"
                    onClicked: footerRootItem.replace()
                }//替换选中行的数据
            }
    
        }//footer属性允许我们制定listview的页脚,footerItem保存了footer组件创建出来的item对象,这个item会被
        //添加到listview的末尾,在所有可见的item之后
    
        Component{
            id: phoneDelegate
            Item {
                id: wrapper
                 parent.width
                height: 30
    
                MouseArea{
                    anchors.fill: parent
                    onClicked: wrapper.ListView.view.currentIndex = index
                    onDoubleClicked: wrapper.ListView.view.model.remove(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
                    }//coll text is end
    
                    Text{
                        text: cost
                        color: wrapper.ListView.isCurrentItem ? "red" : "black"
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.preferredWidth: 80
                    }//cost text is end
    
                    Text{
                        text: manufacturer
                        color: wrapper.ListView.isCurrentItem ? "red" : "black"
                        font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
                        Layout.fillWidth: true
                    }//manufacturer is end
                }
            }
        }//delegate is end(视图的委托)
    
        ListView{
            id: listView
            anchors.fill: parent
            focus: trues
            delegate: phoneDelegate
            model: phoneModel.createObject(listView)
            header: headView
            footer: footerView
            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 changeItem()//修改模型数据
            {
                listView.model.setProperty(listView.currentIndex, "manufacturer", "China")
            }
    
            function replaceItem()//替换模型数据
            {
                listView.model.set(listView.currentIndex, {"name": "234 ninbi",                                                    "cost": 1999, "manufacturer": "ZhongXing"})
            }
    
            Component.onCompleted: {
                listView.footerItem.clean.connect(listView.model.clear)//关联信号
                listView.footerItem.change.connect(listView.changeItem)//关联改变信号
                listView.footerItem.replace.connect(listView.replaceItem)
            }
        }//定义listview
    }
    View Code
    这个例子比较简单,增加了头和footer。另外,在下面放了几个按钮,用以演示对数据的修改和删除。如果要实现插入数据,那么需要在footerView中添加signal insert()

     ,并添加Button

    Button{         id: insertOne
                    anchors.right: addOne.left
                    anchors.leftMargin: 4
                    anchors.verticalCenter: parent.verticalCenter
                    text: "Insert"
                    onClicked: footerRootItem.insert()
                }

    并且在 listView中实现Insert函数、建立与footerView的信号链接

     function addOne()
            {
                model.append(
                    {
                        "name": "MX5",
                        "cost": "1899",
                        "manufacture" : "MeiZu"
                    }
                )
            }
    
            function insertOne()
            {
                model.insert(Math.round(Math.random() * model.count),
                   {
                        "name" : "HTC One E8",
                        "cost" : "2900",
                        "manufacture" : "HTC"
                   }
                )
            }
    
            Component.onCompleted: {
                listView.footerItem.add.connect(listView.addOne)
                listView.footerItem.insert.connect(listView.insertOne)
            }

    注意虽然delegate有很多附加属性以及信号等,但是只有顶层的item才能直接使用这些属性,
    非顶层的item需要通过顶层item的id来访问这些属性

  • 相关阅读:
    每日日报
    每日日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated"}
    2020.11.07
    2020.11.05
    2020.11.09
  • 原文地址:https://www.cnblogs.com/SaveDictator/p/8192391.html
Copyright © 2011-2022 走看看