一直想要一个动态菜单,可随意配置,知道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放入新的文件中了。