4
votes

I need to create nested list view and as shown below, and highlight the main list and sub-list with different color I have tried with ListView highlight but there are issue like the highlight showing for child as well as parent as shown below image.

I am using the code from here with some minor modification.

Here is the full code

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 image description here

How can I overcome this issue. Basically I need to highlight Parent and child Item with different color.

Edit:

I can highlight parent list using the code

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

but coud'nt a find similar way to change the color of child list (sub list) on click.

1

1 Answers

4
votes

Change the color property of the delegate in subItemRepeater to your choice.

Example

Component {
    id: subItemColumnDelegate
    Column {
        ...
        Repeater {
            id: subItemRepeater
            delegate: Rectangle {
                ...
                color: "purple"
                ...
            }
        }
    }
}

Similarly change the color property categoryItem in the categoryDelegate. Example

Component {
    id: categoryDelegate
    Column {
        ...
        Rectangle {
            id: categoryItem
            ...
            color: "blue"
            ...
        }
    }
}

EDIT:

In that case the the overall concept is wrong. In the comment of the original code the author has written A ListElement can't contain child elements, but it can contain a list of elements. So we can't highlight the child item. But the following approach will give good result to you.

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