Creating a Menu Page

到现在,我们(的教程)已经涵盖了如何在单一的QML文件中创建元素和指定行为。在这一节,我们的内容将包含怎样导入QML元素和如何复用一些创建好的组件来生成其他组件。

 

菜单显示一个内容列表,每一项都能执行一个动作。我们可以通过几种方式在QML创建一个菜单。首先,我们建立一个包含按钮的菜单,每个按钮最终都会执行不同动作。菜单代码在FileMenu.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关键字。FileMenu.qml需要用到JavaScript文件,或者不在同级目录下的QML文件。因为Button.qml和FileMenu.qml在同一个目录,我们不需要引入就可以使用它。我们可以通过声明Button{}来直接创建一个Button元素 ,类似于一个Rectangle{}的声明。

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中,我们声明了三个Button元素。它们在一个Row元素里,它作为定位器将它的孩子们沿着一个垂直的行安放。Button的声明在Button.qml中,与上节我们用到的Button.qml是一样的。在新创建的按钮里可以声明绑定新的属性,实际上也覆盖了Button.qml中的属性集。当exitButton按钮被点击时,窗口会被退出并关闭。注意,除了exitButton内的onButtonClick handler会被调用之外,Button.qml内的也会被调到。

Qt Quick 译05 - 开始使用QML编程(2) 

 

Rectangle内声明的Row,创建了一个容纳一行button的容器。这个额外的矩形创造了一种在菜单内组织一行button的间接方法。

 

现阶段,编辑菜单的声明非常简单,有三个标签分别是Copy、Paste和Select All的按钮。

 

Qt Quick 译05 - 开始使用QML编程(2)

装备了导入和定制之前生成的组件的知识,现在我们可以将这些菜单页组合成一个菜单栏——包含用来选择菜单的按钮,并且看看那我们怎样使用QML组织数据。

Implementing a Menu Bar

我们的文本编辑器程序需要一种使用菜单栏显示菜单的方法。使用菜单栏可以切换不同的菜单,用户可以选择要显示的菜单。菜单切换意味着这些菜单比单单在一行中显示出来需要更多的结构。QML使用models和views来构建数据并显示这些结构化的数据。

Using Data Models and Views

QML有不同的数据views可以显示数据models。我们的菜单栏会将菜单显示在一个列表中,这个列表有一个显示一行菜单名的标题。我们可以在VisualItemModel中声明一个菜单列表。VisualItemModel包含了像Rectangle和导入的UI元素这样的views的items。其他的像ListModel元素这样的model类型需要一个代理来显示它们的数据。

 

我们在menuListModel中声明了两个可视的items,FileMenuEditMenu。我们定制了两个菜单,并使用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元素将按照一个delegate来显示一个model。这个delegate可能声明在一个Row元素或则grid元素里显示的model items。我们的menuListModel已经有可见的items,因为,我们就不需要一个delegate了。

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
         model: menuListModel

         //control the movement of the menu switching
         snapMode: ListView.SnapOneItem
         orientation: ListView.Horizontal
         boundsBehavior: Flickable.StopAtBounds
         flickDeceleration: 5000
         highlightFollowsCurrentItem: true
         highlightMoveDuration:240
         highlightRangeMode: ListView.StrictlyEnforceRange
     }

另外,ListView继承自Flickable,使list可以响应鼠标拖拽和其他手势。上面代码的最后一部分设置了Flickable属性,对view创建了我们期待的闪烁移动。特别是highlightMoveDuration属性改变闪烁转变的过渡时间。highlightMoveDuration的值越大菜单切换越慢。

 

ListView通过index来维护所有的model的items,通过index被声明的顺序,可以访问model中的每一个可见item。改变currentIndex实际上改变了ListView中的高亮item。我们的菜单栏的标题以实例证明了这种效果。一行里有两个按钮,当被点击时,两个都会改变当前的菜单。当点击fileButton时,会改变当前的菜单到文件菜单,index为0的原因是,FileMenumenuListModel中是第一个声明的。同样地,点击editButton时改变当前菜单到EditMenu。

 

labelList的zvalue为1,表示它显示在菜单栏前面。z值高的items显示在低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
             }
         }
     }

 

我们刚刚建立的菜单栏可以通过轻打或者点击顶端的菜单名字访问菜单。切换菜单的屏幕感觉起来直观而且反应很快。

Qt Quick 译05 - 开始使用QML编程(2)

相关文章: