27. Use XmlListModel to load XML data for use by ListView and GridView

illustrate:

Personal understanding: XmlListModel uses an xml file as a data source, and the data file specified by xml is a read-only data source. Unless the content in the xml file is manually changed, other methods cannot directly or indirectly change the data. Compare Safety.
Case effect display:

ListView combined with GridView to learn to use xml data

1. Brief description of xml syntax:

The purpose of the xml file itself is to store data, not to display data, so the requirements for syntax are not very strict. Although the data is defined in the form of tags, the tags themselves can be set at will. Before defining the data, first Declare the type of document, for example:

<?xml version="1.0" encoding="utf-8"?>  <!--这个是文档声明,是必须要写的-->

<!--
	下面的标签都是自己指定的,每一个标签之间的文本数据都是对应标签存储的内容
	标签要成对出现
	一般情况下只能有一个根标签,标签内可以有多个子元素
-->
<content>
        <model>
                <icon>qrc:/imgs/QQ.png</icon>
                <titleName>QQ</titleName>
        </model>
        <model>
                <icon>qrc:/imgs/WeChat.png</icon>
                <titleName>微信</titleName>
        </model>
        <model>
                <icon>qrc:/imgs/QQ.png</icon>
                <titleName>QQ</titleName>
        </model>
        <model>
                <icon>qrc:/imgs/WeChat.png</icon>
                <titleName>微信</titleName>
        </model>
        <model>
                <icon>qrc:/imgs/QQ.png</icon>
                <titleName>QQ</titleName>
        </model>
        <model>
                <icon>qrc:/imgs/WeChat.png</icon>
                <titleName>微信</titleName>
        </model>
        <model>
                <icon>qrc:/imgs/QQ.png</icon>
                <titleName>QQ</titleName>
        </model>
        <model>
                <icon>qrc:/imgs/WeChat.png</icon>
                <titleName>微信</titleName>
        </model>

</content>

2. How to use XmlListModel:

Generally specify two attributes, as follows:
query: specify the node path of the query in the xml file
source: specify the address
of the xml file When you need to extract the node data in the xml file, use XmlRol , this class generally also specifies two attributes, as follows:
query: specify the node name and node data type of the query
name: specify the node name of the query
For example:

XmlListModel {
    
    
    source: "qrc:/videoAPP.xml"  // 指定xml文件的路径
    query: "/content/model"		 // 指定在xml文件中节点查询路径(根据上面xml文件的节点定义格式,可以在/content/model节点下查询到icon、titleName这两个节点的内容)

    XmlRole {
    
    	
        name: "icon"	// 这个名称指定的是在xml文件中查询到数据后,在qml中进行引用时所使用的名称(一般和节点名保持一致即可)
        query: "icon/string()" // 指定节点名 icon 和数据类型 string 
    }

    XmlRole {
    
    
        name: "titleName"	// 这个名称指定的是在xml文件中查询到数据后,在qml中进行引用时所使用的名称(一般和节点名保持一致即可)
        query: "titleName/string()"		// 指定节点名 titleName 和数据类型 string 
    }
}

3. Use cases:

QML making drawer menu box

The overall implementation method is to use a ListView and GridView control, where each item in the ListView is a GridView, and each GridView is placed with different sub-elements, and the model and delegate are used to specify the source of the data in both the listview and the gridview and the display style of the data. The specific explanation is as follows:
first place a listview control in main.qml , add the xml path data and the title name of each drawer in the model attribute in the control, and use a custom control libraryview in its attribute delegate to design each The display form of data in listView, the code is as follows:
main.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.3
import QtQuick.XmlListModel 2.0

Window {
    
    
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    
    Rectangle {
    
    //左侧
        id: frame1
        width: 200
        height: parent.height * 0.8
        anchors.centerIn: parent
        color: "#232323"
        border.color: "black"
        border.width: 1
        radius: 20
        
        ListView {
    
    
            spacing: 10
            x:spacing + 8
            y:spacing
            height: parent.height-spacing*2
            width: parent.width-spacing
            interactive: true
            contentWidth: width-25
            clip: true
            model: ListModel {
    
    
                ListElement {
    
    
                    name: qsTr("聊天工具")	// 当前listview数据项的标题
                    xml: "qrc:/chatAPP.xml" // 当前数据项中所用到的xml文件路径
                }
                
                ListElement {
    
    
                    name: qsTr("日常生活")
                    xml: "qrc:/dayLife.xml"
                }
                
                ListElement {
    
    
                    name: qsTr("视频娱乐")
                    xml: "qrc:/videoAPP.xml"
                }
            }
            
            delegate: LibraryView {
    
    	// listview代理项是一个LibraryView(自封装的GridView)
                id: libraryDelegate
                library_name: name
                width: ListView.view.contentWidth
                property url xmlPath: xml
                model: XmlListModel {
    
    	// 数据项使用 xmllistmodel
                    source: libraryDelegate.xmlPath		// source 属性即为每一个listelement当中的xml属性
                    query: "/content/model"		// 设定节点查询路径
                    
                    // 这里使用的每一个XmlRole都和xml文件中自定义的属性个数一一对应,有多少个属性就用多少个XmlRole去查询
                    XmlRole {
    
    
                        name: "icon"	// 指定数据查询到之后,引用时所使用的标题名
                        query: "icon/string()"	// 指定查询的节点名和类型
                    }
                    
                    XmlRole {
    
    
                        name: "titleName"
                        query: "titleName/string()"
                    }
                    
                }
            }
            
        }
    }
    
}

In the above-mentioned LibraryView.qml, only the data source of the libraryview (gridview) is set, but it is also necessary to set the display form of each libraryview (gridview), the code is as follows:
LibraryView.qml

import QtQuick 2.15
import QtQuick.Controls 2.15

GridView {
    
    
    id: libraryView
    property string library_name
    implicitWidth: 100
    //整体gridview的高度和header有关,点击header显示整个gridview,否则只显示header
    implicitHeight: headerItem.height + (headerItem.checked ? cellHeight * Math.ceil(model.count / 2) : 0)

    interactive: false
    cellHeight: 80  // 高度可以始终保持不变
    cellWidth: width / 2    // width / num (num是指定每一行有几个元素)
    header: Button {
    
    	// 指定gridview的header的显示形式
        id:btnHeader
        checkable: true
        width: libraryView.width
        font.pointSize: 12
        text: libraryView.library_name	// 这里的library_name是从libraryview中传输过来的
        contentItem: Text{
    
    
            text: btnHeader.text
            font: btnHeader.font
            opacity: enabled ? 1.0 : 0.3
            color: btnHeader.checked ? "#FFFFFF" : "#E9622A"
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            elide: Text.ElideRight
        }

        background: Rectangle {
    
    
            border.color: "#E9622A"
            border.width: 1
            color: btnHeader.checked ? "#E9622A" : Qt.rgba(1.0,1.0,1.0,0.0)
            radius: 10
        }
    }
    delegate: Item {
    
    	// 定义 gridview 中每一个元素的显示样式
        id: libraryDelegate
        width: GridView.view.cellWidth
        height: GridView.view.cellHeight
        visible: libraryDelegate.GridView.view.headerItem.checked
        opacity: enabled ? 1 : 0.5


        IconMask {
    
    	//这里又用到了另外一个自定义的组件,用于设计每一个gridview子元素的显示样式
            id: tile
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter

            icon_source: icon	// 这个 icon 就是从xml查询得到的,也是XmlRole当中的name属性
            name_text: titleName // 这个 titleName 也是从xml查询得到的,也是第二个XmlRole当中的name属性

            MouseArea{
    
    
                id:iconMouse
                anchors.fill: parent
                onPressed: {
    
    
                    iconFrame.scale = 0.9
                }
                onReleased: {
    
    
                    iconFrame.scale = 1.0
                }
            }
        }

    }
}

In the above IconMask custom file, continue to design the display style of each icon, the specific code is as follows:
IconMask.qml

import QtQuick 2.15

Item {
    
    
    implicitWidth: iconFrame.width
    implicitHeight: iconFrame.height + name_height
    property alias iconFrame_height: iconFrame.height
    property alias icon_source: iconImg.source	// 将上面代码中查询到的图像路径数据传输给指定控件的属性
    property alias name_text: name.text	// 将上面代码中查询到的名称数据传输给指定控件的属性
    property real name_height: name.height + iconFrame.anchors.topMargin

    Text {
    
    
        id: name
        anchors.horizontalCenter: parent.horizontalCenter
        font.pointSize: 9
        color: "white"
    }

    Rectangle {
    
    
        id: iconFrame
        width: 50
        height: width
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: name.bottom
        anchors.topMargin: 5
        color: parent.parent.isChoices ? "lightblue" : "#eeeeee"
        border.color: "#ffffff"
        radius: 5

        Image {
    
    
            id: iconImg
            width: parent.width * 0.7
            height: parent.height * 0.7
            anchors.centerIn: parent
        }

    }
}

4. The code structure is as follows:

insert image description here

5. The specific effects are as follows:

insert image description here

Continuously updating, please pay more attention to...

Guess you like

Origin blog.csdn.net/FY_13781298928/article/details/129792598