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
}
}
}