创建菜单页
上节中阐述了如何创建元素并在单独的QML文件中设置行为.本节将说明如何导入QML元素,如何重用已有组件构建其他组件.
菜单显示一列内容,其中的每个项都可以执行一个动作.在QML中,有很多种方式创建菜单.首先,我们创建包含可执行不同动作按钮的菜单.菜单代码在FileMenu.qml中.
import QtQuick 1.0 \import the main Qt QML module
import “folderName” \import the contents of the folder
import “script.js” as Script \import a Javascript file and name it as Script
上述语法展示如何使用import关键字.这里需要使用不在同一目录中的JavaScript文件或QML文件.由于Button.qml与FileMenu.qml在同一目录中,不必导入Button.qml就可直接使用.可直接使用Button{}声明一个按钮元素,与Rectangle{}的声明一样.
FileMenu.qml:
Row{
anchors.centerIn: parent
spacing: parent.width/6
Button{
id: loadButton
buttonColor: "lightgrey"
label: "Load"
}
Button{
buttonColor: "grey"
id: saveButton
label: "Save"
}
Button{
id: exitButton
label: "Exit"
buttonColor: "darkgrey"
onButtonClick: Qt.quit()
}
}
在FileMenu.qml中,声明了三个按钮元素.他们都在一个Row元素中声明的,这是一个定位器,将其子元素按行定位.Button声明在Button.qml中,与上节定义的Button.qml一致.新创建的按钮可设置属性绑定,在exitButton上增加了onButtonClick处理函数,由Button.qml中定义的onButtonClick来触发调用.

Row定义在Rectangle中,创建了包含一行按钮的矩形容器.这个额外的矩形采用间接的方式在菜单中组织了一行按钮.
这个阶段定义的编辑菜单非常简单.菜单按钮具有的标签为:Copy,Paste,Select All.

结合前面介绍的知识和定义的组件,我们已经可以组合这些菜单页生成一个菜单栏了,包括选择菜单的按钮,下面看看如何在QML中组织这些数据.
实现菜单栏
我们的文本编辑器程序需要使用菜单栏显示菜单.菜单栏可以切换不同的菜单,用户可选择显示哪个菜单.菜单间的切换比仅仅显示在一行中需要更多组织信息.QML使用模型和视图来组织数据和显示数据.
使用数据模型和视图
QML有用来显示数据模型(data models)的不同的数据视图(data views ).我们的菜单栏将显示列表中的菜单,头部显示一行菜单名称.菜单列表定义在VisualItemModel中.VisualItemModel元素中包含需要显示的元素,如Rectangle元素和导入的UI元素.其他模型类型如 ListModel 元素则需要显示其数据的代理(视图).
我们在menuListModel中定义两个可视化项,一个FileMenu一个EditMenu.并自定义这两个菜单,显示在ListView中.MenuBar.qml文件包含了简单的QML定义,编辑菜单定义在EditMenu.qml中.
VisualItemModel{
id: menuListModel
FileMenu{
width: menuListView.width
height: menuBar.height
color: fileColor
}
EditMenu{
color: editColor
width: menuListView.width
height: menuBar.height
}
}
ListView元素用来显示其代理模型.代理声明可在Row元素中显示模型元素,也可在Grid中显示模型元素.menuListModel已经定义需要显示的项了,因此,我们不再需要声明模型了.
ListView{
id: menuListView
//Anchors are set to react to window anchors
anchors.fill:parent
anchors.bottom: parent.bottom
width:parent.width
height: parent.height
//the model contains the data
[b]model: menuListModel[/b]
//控制菜单开关的移动
snapMode: ListView.SnapOneItem
orientation: ListView.Horizontal
boundsBehavior: Flickable.StopAtBounds
flickDeceleration: 5000
highlightFollowsCurrentItem: true
highlightMoveDuration:240
highlightRangeMode: ListView.StrictlyEnforceRange
}
另外,ListView从Flickable继承,使列表可响应鼠标拖拽和手势.上述代码的最后部分设置flick属性可在视图中创建出期望的flick移动效果.特别是highlightMoveDuration属性设置flick的延续时间.较高的highlightMoveDuration值使菜单切换变慢.
ListView通过索引维护模型项目,模型中的可视项都是通过索引进行访问的,索引顺序与声明顺序相同.修改当前索引值会改变ListView中的高亮项.菜单栏的头部分证实了这个效果.这里一行中有两个按钮,点击后会改变当前菜单.点击fileButton将当前菜单切换为file菜单,由于FileMenu在menuListModel中第一个声明,因此其索引为0.同样,点击editButton将当前菜单切换为EditMenu.
labelList矩形的z属性值为1,强调其显示在菜单栏的最前面.项的z属性值越高越靠前显示.z属性值默认为0.
Rectangle{
id: labelList
...
z: 1
Row{
anchors.centerIn: parent
spacing:40
Button{
label: "File"
id: fileButton
...
onButtonClick: menuListView.currentIndex = 0
}
Button{
id: editButton
label: "Edit"
...
onButtonClick: menuListView.currentIndex = 1
}
}
}
菜单栏可以通过flick操作或点击上面的菜单名称按钮.切换菜单效果很直观生动.
