QML之动态菜单配置

一直想要一个动态菜单,可随意配置,知道QtQuick中找到一个Views Examples。非常有用,记录如下。

界面:


点击每项,进行界面跳转,例如点击第一项跳转:


LaunchList.qml

import QtQuick 2.0

Rectangle {
    //model is a list of {"name":"somename", "url":"file:///some/url/mainfile.qml"}
    //function used to add to model A) to enforce scheme B) to allow Qt.resolveUrl in url assignments

    color: "#eee"
    function addExample(name, desc, url)
    {
        myModel.append({"name":name, "description":desc, "url":url})
    }
    function hideExample()
    {
        ei.visible = false;
    }

    ListView {        
        clip: true
        delegate: SimpleLauncherDelegate{exampleItem: ei}
        model: ListModel {id:myModel}
        anchors.fill: parent
    }

    Item {
        id: ei
        visible: false
        clip: true
        property url exampleUrl
        onExampleUrlChanged: visible = (exampleUrl == '' ? false : true); //Setting exampleUrl automatically shows example
        anchors.fill: parent
        anchors.bottomMargin: 40
        Rectangle {
            id: bg
            anchors.fill: parent
            color: "white"
        }
        MouseArea{
            anchors.fill: parent
            enabled: ei.visible
            //Eats mouse events
        }
        Loader{
            focus: true
            source: ei.exampleUrl
            anchors.fill: parent
        }
    }
    Rectangle {
        id: bar
        visible: ei.visible
        anchors.bottom: parent.bottom
        width: parent.width
        height: 40

        Rectangle {
            height: 1
            color: "#ccc"
            anchors.top: parent.top
            anchors.left: parent.left
            anchors.right: parent.right
        }

        Rectangle {
            height: 1
            color: "#fff"
            anchors.top: parent.top
            anchors.topMargin: 1
            anchors.left: parent.left
            anchors.right: parent.right
        }

        gradient: Gradient {
            GradientStop { position: 0 ; color: "#eee" }
            GradientStop { position: 1 ; color: "#ccc" }
        }

        MouseArea{
            anchors.fill: parent
            enabled: ei.visible
            //Eats mouse events
        }

        Image {
            id: back
            source: "images/back.png"
            anchors.verticalCenter: parent.verticalCenter
            anchors.verticalCenterOffset: 2
            anchors.left: parent.left
            anchors.leftMargin: 16

            MouseArea {
                id: mouse
                hoverEnabled: true
                anchors.centerIn: parent
                width: 38
                height: 31
                anchors.verticalCenterOffset: -1
                onClicked: ei.exampleUrl = ""
                Rectangle {                    
                    anchors.fill: parent
                    opacity: mouse.pressed ? 1 : 0
                    Behavior on opacity { NumberAnimation{ duration: 2000 }}
                    gradient: Gradient {
                        GradientStop { position: 0 ; color: "#22000000" }
                        GradientStop { position: 0.2 ; color: "#11000000" }
                    }
                    border.color: "darkgray"
                    antialiasing: true
                    radius: 4
                }
            }
        }
    }
}

菜单项SimplelaunchDelegate:

import QtQuick 2.0

Rectangle {
    id: container
    property Item exampleItem
    width: ListView.view.width
    height: button.implicitHeight + 22

    gradient: Gradient {
        GradientStop {
            position: 0
            Behavior on color {ColorAnimation { duration: 100 }}
            color: button.pressed ? "#e0e0e0" : "#fff"
        }
        GradientStop {
            position: 1
            Behavior on color {ColorAnimation { duration: 100 }}
            color: button.pressed ? "#e0e0e0" : button.containsMouse ? "#f5f5f5" : "#eee"
        }
    }
    //Image Button
    Image {
        id: image
        opacity: 0.7
        Behavior on opacity {NumberAnimation {duration: 100}}
        source: "images/next.png"
        anchors.verticalCenter: parent.verticalCenter
        anchors.right: parent.right
        anchors.rightMargin: 16
    }
    //Menu Item
    Item {
        id: button
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.bottom: parent.bottom
        anchors.right:image.left
        implicitHeight: col.height
        //height: implicitHeight
        //width: buttonLabel.width + 20

        MouseArea {
            id: mouseArea
            anchors.fill: parent
            onClicked: exampleItem.exampleUrl = url
            hoverEnabled: true
        }

        Column {
            spacing: 2
            id: col
            anchors.verticalCenter: parent.verticalCenter
            width: parent.width
            Text {
                id: buttonLabel
                anchors.left: parent.left
                anchors.leftMargin: 10
                anchors.right: parent.right
                anchors.rightMargin: 10
                text: name
                color: "black"
                font.pixelSize: 22
                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                styleColor: "white"
                style: Text.Raised

            }
            Text {
                id: buttonLabel2
                anchors.left: parent.left
                anchors.leftMargin: 10
                text: description
                wrapMode: Text.WrapAtWordBoundaryOrAnywhere
                color: "#666"
                font.pixelSize: 12
            }
        }
    }

    Rectangle {
        height: 1
        color: "#ccc"
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.right: parent.right
    }
}

用户声明LaunchList,通过调用addExample为LaunchList添加启动项。这些信息被保存到ListModel中,并被SimpleLauchDelegate显示出Title,Description信息。

当Delegate被点击时,通过ListModel可以得到启动项的url信息,将url付给Loader就能将url的界面显示出来。

新界面被启动后,item.exampleUrl为非空,从而是的bar.visible为true。

点击bar后,将item.exampleUrl又设置为空,从而导致item所代表的界面visible为false,新界面被隐藏(被卸载,Loader.source="")。界面又回到了启动列表。


实际上可以将bar放入ei中,将bottomMargin去掉,然后将Loader放入新的Rectangle中,Bar放在新的Rectangle下面。这样就能将ei作为一个Component放入新的文件中了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值