Proper way to create accordion control using qml

2019-02-20 16:47发布

I'm trying to create accordion qml control like this. First I thought that I can use combobox and customize it but now I think it is impossible. Is there any standerd control that I can use? If not can you help me with controls structure?

标签: qt qml
3条回答
家丑人穷心不美
2楼-- · 2019-02-20 17:11

Just playing with QML

PanelItem.qml

import QtQuick 2.7
import QtQuick.Layouts 1.2

Item {
    default property var contentItem: null
    property string title: "panel"
    id: root
    Layout.fillWidth: true
    height: 30
    Layout.fillHeight: current
    property bool current: false
    ColumnLayout {
        anchors.fill: parent
        spacing: 0
        Rectangle {
            id: bar
            Layout.fillWidth: true
            height: 30
            color:  root.current ? "#81BEF7" : "#CEECF5"
            Text {
                anchors.fill: parent
                anchors.margins: 10
                horizontalAlignment: Text.AlignLeft
                verticalAlignment: Text.AlignVCenter
                text: root.title
            }
            Text {
                anchors{
                    right: parent.right
                    top: parent.top
                    bottom: parent.bottom
                    margins: 10
                }
                horizontalAlignment: Text.AlignRight
                verticalAlignment: Text.AlignVCenter
                text: "^"
                rotation: root.current ? "180" : 0
            }
            MouseArea {
                anchors.fill: parent
                cursorShape: Qt.PointingHandCursor
                onClicked: {
                    root.current = !root.current;
                    if(root.parent.currentItem !== null)
                        root.parent.currentItem.current = false;

                    root.parent.currentItem = root;
                }
            }
        }
        Rectangle {
            id: container
            Layout.fillWidth: true
            anchors.top: bar.bottom
            implicitHeight: root.height - bar.height
            clip: true
            Behavior on implicitHeight {
                PropertyAnimation { duration: 100 }
            }
        }
        Component.onCompleted: {
            if(root.contentItem !== null)
                root.contentItem.parent = container;
        }
    }
}

usage:

import QtQuick 2.7
import QtQuick.Layouts 1.2
import QtQuick.Window 2.0

Window {
    visible: true
    width: 400
    height: 400

    ColumnLayout {
        anchors.fill: parent
        spacing: 1
        property var currentItem: null
        PanelItem {
            title: "Panel 1"
            Rectangle {
                color: "orange"
                anchors.fill: parent
            }
        }
        PanelItem {
            title: "Panel 2"
            Rectangle {
                color: "lightgreen"
                anchors.fill: parent
            }
        }
        PanelItem {
            title: "Panel 3"
            Rectangle {
                color: "lightblue"
                anchors.fill: parent
            }
        }
        PanelItem {
            title: "Panel 4"
            Rectangle {
                color: "yellow"
                anchors.fill: parent
            }
        }
        Item {
            Layout.fillWidth: true
            Layout.fillHeight: true
        }
    }
}
查看更多
贼婆χ
3楼-- · 2019-02-20 17:12

Updating the MouseArea click part as below with some added condition. Thanks to folibis for this qml accordian menu.

MouseArea {
    anchors.fill: parent
    cursorShape: Qt.PointingHandCursor
    onClicked: {
        root.current = !root.current;
        if(root.parent.currentItem !== null) {
            if(root.parent.currentItem !== root)
                root.parent.currentItem.current = false;
        }

        root.parent.currentItem = root;
    }
}
查看更多
可以哭但决不认输i
4楼-- · 2019-02-20 17:19

What about using this open source component which I did here Accordion component and used here Accordion component example.

You only need to initialize:

Components.Accordion {
    id: acordion
    anchors.fill: parent
    anchors.margins: 10
}

And create the data dynamically like this:

propertyAcordion.model = [
{
    'menuTitle': value,
    'children': [
        {
            'menuTitle': value,
            'children': [
...
查看更多
登录 后发表回答