感谢这两位大佬:
https://blog.csdn.net/luoyayun361/article/details/81585101
https://blog.csdn.net/gongjianbo1992/article/details/90575519
核心
一级架构:直接使用listElement
二级架构:使用孩子元素,其中孩子元素为键值对;用repeater
来调用孩子元素
三级架构:不使用repeater
,而是再次使用listView
;再展示其孩子,即第三代。
不足
布局不好看,大伙自己调一调。
效果展示
代码如下
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
Item
{
id: simulation_edit_control_item_id
ListModel {
id: myModel
Component.onCompleted:
{
function findIndex(fatherName)
{
for(var i = 0 ; i < myModel.count ; ++i)
{
if(myModel.get(i).name === fatherName)
{
return i
}
}
return -1
}
function addModelData(fatherName,picture_source,name)
{
var index = findIndex(fatherName)
//console.log("fatherName:...",index)
if(index === -1)
{
//如果不存在,则它自己作为新的父节点
myModel.append({"name":fatherName,"picture_source":picture_source,"level":0,"thSubNode":[]})
}
}
var listMenu=[ "四轮车", "二轮车" , "人" ]
var source=""
//创建父列表
for(var i=0;i<3;i++)
{
source=""
addModelData(listMenu[i],source,"" );
}
myModel.get(0).thSubNode.append({"name":"小汽车","picture_source":"","level":1,"subNode":[]})
myModel.get(1).thSubNode.append({"name":"摩托车","picture_source":"","level":1,"subNode":[]})
myModel.get(1).thSubNode.append({"name":"自行车","picture_source":"","level":1,"subNode":[]})
myModel.get(2).thSubNode.append({"name":"行人","picture_source":"","level":1,"subNode":[]})
myModel.get(2).thSubNode.get(0).subNode.append({"name":"行人行人","picture_source":"","level":2})
myModel.get(1).thSubNode.get(0).subNode.append({"name":"自行车零件","picture_source":"","level":2})
//console.log("hello",myModel.get(1).subNode.get(0).thSubNode.name)
}
}
Component
{
id:list_delegate
Column
{
id:objColumn
leftPadding: 20
Component.onCompleted:
{
//默认展开列表
for(var i = 1; i < objColumn.children.length - 1; ++i)
{
objColumn.children[i].visible = true
}
}
Row
{
spacing:10
leftPadding: 10
Rectangle
{
id:list_rect
width:220
height:30
color:"#EDF1F2"
Image
{
id: icon
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: 6
anchors.leftMargin: 3
width: 20
height: 20
source: picture_source //来自myModel的一级列表图标路径属性
}
Text
{
id: list_name
x:icon.x + icon.width +11
y: icon.y
width: 24
height: 19
text: name //来自myModel的一级列表名字属性
font.styleName: "Regular"
font.pixelSize: 12
color: "#505559"
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
}
Item
{
width: 220
height:180
//border.color: "blue"
//需要加个item来撑开,如果用Repeater获取不到count
ListView
{
id: item_repeater
anchors.fill: parent
anchors.top: parent.top
anchors.topMargin:5
//spacing: 20
orientation: ListView.Vertical //垂直列表
interactive: true; //元素可用鼠标滚轮
clip: true //限制顶部,使得不超出区域
boundsBehavior:Flickable.StopAtBounds //listview不跳动
delegate: subNode_delegate
model: thSubNode
}
}
}
}
Component
{
id:subNode_delegate
//重复排布myModel的子节点subNode
Column
{
leftPadding:10
Rectangle
{ //子物体展示,如车辆、行人的图片、文字信息。
id:role_rect_id
x:0
y:0
width: 210
height: 40
border.color:"grey"
Image
{
id: role_icon
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: 8
anchors.leftMargin: 28
width: 50
height: 50
source: picture_source
fillMode: Image.PreserveAspectFit
}
Text
{
id: list_name_id
x:role_icon.x + role_icon.width + 9
y:role_icon.y
width: 65
height: 19
text: name
font.styleName: "Regular"
font.pixelSize: 12
color: "#505559"
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
Repeater
{
model:subNode
delegate:
Rectangle
{
id:role_rect
x:20
y:0
width: 190
height: 70
border.color:"green"
Image
{
id: icon
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: 8
anchors.leftMargin: 28
width: 50
height: 50
source: picture_source
fillMode: Image.PreserveAspectFit
}
Text
{
id: list_name
x:role_icon.x + role_icon.width + 9
y:role_icon.y
anchors.top: parent.top
anchors.topMargin: 24
width: 65
height: 19
text: name
font.styleName: "Regular"
font.pixelSize: 12
color: "#505559"
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
}
}
}
ListView
{
id:listView
anchors.fill: parent
anchors.top: parent.top
anchors.topMargin:20
spacing: 20
orientation: ListView.Vertical //垂直列表
interactive: true; //元素可用鼠标滚轮
clip: true //限制顶部,使得不超出区域
boundsBehavior:Flickable.StopAtBounds //listview不跳动
model:myModel
delegate: list_delegate
}
MouseArea
{
x:0
y:0
width:0
height:0
// anchors.fill:parent
// hoverEnabled: true
// propagateComposedEvents: true
// onClicked:
// {
// mouse.accepted =false
// }
}
}