关于 qt:QML 带有突出显示的嵌套列表视图

QML Nested List view with Highlight

我需要创建嵌套列表视图,如下所示,并用不同的颜色突出显示主列表和子列表
我已经尝试过使用 ListView 高亮显示,但存在诸如显示子级和父级的高亮显示的问题,如图所示
下图。

我正在使用这里的代码并稍作修改。

这是完整的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.1

ApplicationWindow {

    id: loginWindow
    //visibility:"Maximized"
    visible: true
    width: 720
    height: 720

    Item {
        width: 200
        height: 720

        ListView {
            id: list
            anchors.fill: parent
            model: nestedModel
            delegate: categoryDelegate
            highlight: Rectangle {
                color:"#FF00AAFF" //"#FF59ACFF";
                radius: 2
            }
        }

        ListModel {
            id: nestedModel
            ListElement {
                categoryName:"Veggies"
                collapsed: true

                // A ListElement can't contain child elements, but it can contain
                // a list of elements. A list of ListElements can be used as a model
                // just like any other model type.
                subItems: [
                    ListElement {
                        itemName:"Tomato"
                    },
                    ListElement {
                        itemName:"Cucumber"
                    },
                    ListElement {
                        itemName:"Onion"
                    },
                    ListElement {
                        itemName:"Brains"
                    }
                ]
            }

            ListElement {
                categoryName:"Fruits"
                collapsed: true
                subItems: [
                    ListElement {
                        itemName:"Orange"
                    },
                    ListElement {
                        itemName:"Apple"
                    },
                    ListElement {
                        itemName:"Pear"
                    },
                    ListElement {
                        itemName:"Lemon"
                    }
                ]
            }

            ListElement {
                categoryName:"Cars"
                collapsed: true
                subItems: [
                    ListElement {
                        itemName:"Nissan"
                    },
                    ListElement {
                        itemName:"Toyota"
                    },
                    ListElement {
                        itemName:"Chevy"
                    },
                    ListElement {
                        itemName:"Audi"
                    }
                ]
            }
        }

        Component {
            id: categoryDelegate
            Column {
                width: 200

                Rectangle {
                    id: categoryItem
                    border.color:"black"
                    border.width: 5
                    color:"#33FF5225"
                    height: 50
                    width: 200

                    Text {
                        anchors.verticalCenter: parent.verticalCenter
                        x: 15
                        font.pixelSize: 24
                        text: categoryName
                    }

                    Rectangle {
                        color:"red"
                        width: 30
                        height: 30
                        anchors.right: parent.right
                        anchors.rightMargin: 15
                        anchors.verticalCenter: parent.verticalCenter

                        MouseArea {
                            anchors.fill: parent

                            // Toggle the 'collapsed' property
                            onClicked: {
                                list.currentIndex = index
                                nestedModel.setProperty(index,"collapsed",
                                                        !collapsed)
                            }
                        }
                    }
                }

                Loader {
                    id: subItemLoader

                    // This is a workaround for a bug/feature in the Loader element. If sourceComponent is set to null
                    // the Loader element retains the same height it had when sourceComponent was set. Setting visible
                    // to false makes the parent Column treat it as if it's height was 0.
                    visible: !collapsed
                    property variant subItemModel: subItems
                    sourceComponent: collapsed ? null : subItemColumnDelegate
                    onStatusChanged: if (status == Loader.Ready) item.model = subItemModel
                }
            }
        }

        Component {
            id: subItemColumnDelegate
            Column {
                property alias model: subItemRepeater.model
                width: 200
                Repeater {
                    id: subItemRepeater
                    delegate: Rectangle {
                        x: 10
                        color:"#33FF5225"
                        height: 40
                        width: 190
                        border.color:"black"
                        border.width: 2

                        Text {
                            anchors.verticalCenter: parent.verticalCenter
                            x: 30
                            font.pixelSize: 18
                            text: itemName
                        }
                    }
                }
            }
        }
    }
}

enter

1
color:categoryDelegate.ListView.isCurrentItem ?"#FF00AAFF" :"#CCBBBBBB"

但找不到类似的方法来更改点击时子列表(子列表)的颜色。


subItemRepeaterdelegatecolor 属性更改为您的选择。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Component {
    id: subItemColumnDelegate
    Column {
        ...
        Repeater {
            id: subItemRepeater
            delegate: Rectangle {
                ...
                color:"purple"
                ...
            }
        }
    }
}

类似地改变categoryDelegate中的color属性categoryItem
示例

1
2
3
4
5
6
7
8
9
10
11
12
Component {
    id: categoryDelegate
    Column {
        ...
        Rectangle {
            id: categoryItem
            ...
            color:"blue"
            ...
        }
    }
}

编辑:

在这种情况下,整体概念是错误的。在原始代码的注释中作者写了 A ListElement can't contain child elements, but it can contain a list of elements。所以我们不能突出显示子项。但是下面的方法会给你很好的结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import QtQuick 2.0

Rectangle {
    width: 360
    height: 360

    ListModel {
        id: model1

        ListElement {
            name:"name"
        }
        ListElement {
            name:"name"
        }
        ListElement {
            name:"name"
        }
    }
    ListModel {
        id: model2
        ListElement {
            name:"inside"
        }
        ListElement {
            name:"inside"
        }
        ListElement {
            name:"inside"
        }
    }

    ListView {
        id: outer
        model: model1
        delegate: listdelegate
        anchors.fill: parent
    }

    Component {
        id: listdelegate

        Item {
            width: 100
            height: col.childrenRect.height

            Column {
                id: col
                anchors.left: parent.left
                anchors.right: parent.right
                Text {
                    id: t1
                    text: name
                }
                ListView {
                    id: insidelist
                    model: model2
                    property int collapseHeightFlag: childrenRect.height
                    delegate: Component {
                        id: delegate2

                        Item {
                            width: 100
                            height: col2.childrenRect.height

                            Column {
                                id: col2
                                anchors.left: parent.left
                                anchors.right: parent.right
                                Text {
                                    id: name1
                                    text: name
                                }
                            }
                            MouseArea {
                                anchors.fill: parent
                                onClicked: {
                                    insidelist.currentIndex = index;
                                }
                            }
                        }
                    }
                    contentHeight: contentItem.childrenRect.height
                    height: 0
                    anchors.left: parent.left
                    anchors.right: parent.right
                    clip: true
                    highlight: Rectangle {
                        color:"pink"
                        radius: 2
                    }
                    focus: true
                }
            }
            Rectangle {
                color:"red"
                width: 10
                height: 10
                anchors.right: parent.right
                anchors.rightMargin: 5
                anchors.top: parent.top
                anchors.topMargin: 5

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        if(insidelist.height === insidelist.collapseHeightFlag) {
                            insidelist.height = 0;
                        }
                        else
                            insidelist.height = insidelist.collapseHeightFlag;
                    }
                }
            }
        }
    }
}