DNamto
DNamto

Reputation: 1362

ListView issue in QML

I'm trying to develop an application which has multi-layered navigation in drop-downs. Below is the snapshot of the requirement. On clicking QSR only the subitems of QSR should pop out with proper alignment.

original requirement

But with my implementation, I'm getting following result. The pop out window is not aligned, but extending itself to the list.

my implementation

Below is the my code snippet

import QtQuick 1.1

Item {
    width: 500
    height: 300

    ListView {
        anchors.fill: parent
        model: nestedModel
        delegate: categoryDelegate
    }

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

            subItems: [
                ListElement { itemName: "KFC" },
                ListElement { itemName: "Mc Donalds" },
                ListElement { itemName: "Pizza Hut" },
                ListElement { itemName: "Brain's" }
            ]
        }

        ListElement {
            categoryName: "Drinks"
            collapsed: true
            subItems: [
                ListElement { itemName: "Pepsi" },
                ListElement { itemName: "Coke" },
                ListElement { itemName: "7up" },
                ListElement { itemName: "Bacardi" }
            ]
        }
    }

    Component {
        id: categoryDelegate
        Column {
            width: 200

            Rectangle {
                id: categoryItem
                border.color: "black"
                border.width: 5
                color: "white"
                height: 50
                width: 200
                anchors.left: parent.right

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

                MouseArea {
                    anchors.fill: parent
                    onClicked: nestedModel.setProperty(index, "collapsed", !collapsed)
                }

            }


            Loader {
                id: subItemLoader
                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 {
                    color: "#cccccc"
                    height: 40
                    width: 200
                    border.color: "black"
                    border.width: 2

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

Any help to achieve original requirement will be appreciable.

Upvotes: 1

Views: 3172

Answers (1)

sebasgo
sebasgo

Reputation: 3861

Have a close look at the delegate for your main list view: It's Column (put items on top of each over) of the main menu item and Loader for the popup menu. Obviously as soon as you load a popup menu it's displayed under its corresponding menu item in the list.

To get the behavior you intended you have to move the Loader for the popup menu out of the ListView:

import QtQuick 1.1

Item {
    width: 400
    height: 300

    Row {
        anchors.fill: parent

        Loader {
            id: subItemLoader
            width: 200
            height: parent.height
            property variant subItemModel: null
            sourceComponent: subItemModel == null? null: subItemColumnDelegate
            function setModel() {
                if (status == Loader.Ready) item.model = subItemModel
            }
            onStatusChanged: setModel()
            onSubItemModelChanged: setModel()
        }

        ListView {
            width: 200
            height: parent.height
            model: nestedModel
            delegate: categoryDelegate
        }
    }


    ListModel {
        id: nestedModel
        ListElement {
            categoryName: "QSR"

            subItems: [
                ListElement { itemName: "KFC" },
                ListElement { itemName: "Mc Donalds" },
                ListElement { itemName: "Pizza Hut" },
                ListElement { itemName: "Brain's" }
            ]
        }

        ListElement {
            categoryName: "Drinks"
            subItems: [
                ListElement { itemName: "Pepsi" },
                ListElement { itemName: "Coke" },
                ListElement { itemName: "7up" },
                ListElement { itemName: "Bacardi" }
            ]
        }
    }

    Component {
        id: categoryDelegate

        Rectangle {
            id: categoryItem
            border.color: "black"
            border.width: 5
            color: "white"
            height: 50
            width: 200

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

            MouseArea {
                anchors.fill: parent
                onClicked: {
                    if (subItemLoader.subItemModel != subItems)
                        subItemLoader.subItemModel = subItems
                    else
                        subItemLoader.subItemModel = null
                }
            }
        }

    }

    Component {
        id: subItemColumnDelegate
        Column {
            property alias model : subItemRepeater.model
            width: 200
            height: 500
            Repeater {
                id: subItemRepeater
                delegate: Rectangle {
                    color: "#cccccc"
                    height: 40
                    width: 200
                    border.color: "black"
                    border.width: 2

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

}

Upvotes: 1

Related Questions