qml 导航类视图


1、ScrollView

  在另一个Item中提供滚动视图,ScrollView可以用来替换Flickable,也可以装饰现有的Flickable。根据平台的不同,它将添加滚动条和内容框架。

  只有一个Item可以是ScrollView的直接子视图,并且子视图被隐式锚定以填充滚动视图。

  例如:

  ScrollView {
      Image { source: "largeImage.png" }
  }

  在例子中,Image项将隐式地获得滚动行为,就像它在Flickable中使用一样。子项目的宽度和高度将用于定义内容区域的大小。

  可以通过指定ScrollViewStyle为ScrollView创建一个自定义外观。   

  • [default] contentItem : Item      ScrollView的内容。这由用户设置。请注意,contententitem的定义与Flickable的定义有些不同,在Flickable中contententitem是隐式创建的。
  • [read-only] flickableItem : Item   ScrollView的flickableItem。如果提供给ScrollView的contententitem是一个Flickable,它将是contententitem。
  • frameVisible : bool  这个属性告诉ScrollView是否应该在它的内容周围呈现一个框架。缺省值为false。
  • highlightOnFocus : bool       当ScrollView有输入焦点时,这个属性控制框架周围是否应该有高亮显示。缺省值为false。
  • horizontalScrollBarPolicy : enumeration         此属性保存显示水平滚动条的策略。可以是以下任意值(默认策略是Qt.ScrollBarAsNeeded):
    • Qt.ScrollBarAsNeeded
    • Qt.ScrollBarAlwaysOff
    • Qt.ScrollBarAlwaysOn
  • style : Component  此控件的样式组件。
  • verticalScrollBarPolicy : enumeration  此属性保存显示垂直滚动条的策略。可以是以下任意值(默认策略是Qt.ScrollBarAsNeeded):
    • Qt.ScrollBarAsNeeded
    • Qt.ScrollBarAlwaysOff
    • Qt.ScrollBarAlwaysOn
  • viewport : Item  视口决定了contententitem上的当前“窗口”。换句话说,它剪辑它,视口的大小告诉你有多少内容区域是可见的。

  1.1 ScrollViewStyle

  •  control : ScrollView  这个样式所附加的ScrollView
  • corner : Component  此组件绘制滚动条之间的角区
  • decrementControl : Component  该组件控制滚动条递减按钮的外观。可以访问以下状态属性:
    • property bool styleData.hovered

    • property bool styleData.pressed
    • property bool styleData.horizontal
  • frame : Component  这个组件在滚动条周围绘制框架。
  • handle : Component  该组件控制滚动条手柄的外观。可以访问以下状态属性:
    •   property bool styleData.hovered

    •   property bool styleData.pressed
    •   property bool styleData.horizontal
  • handleOverlap : int  此属性控制手柄与递增/递减按钮之间的边缘重叠。缺省值是30。
  • incrementControl : Component  该组件控制滚动条增量按钮的外观。可以访问以下状态属性:  
      • property bool styleData.hovered

      • property bool styleData.pressed
      • property bool styleData.horizontal
  • minimumHandleLength : int  这是滚动条句柄的最小范围。 
  • scrollBarBackground : Component  这个组件控制滚动条背景的外观。可以访问以下状态属性:
    • property bool styleData.hovered

    • property bool styleData.pressed
  • scrollToClickedPosition : bool  该组件决定当单击时,该flickable是否应该在鼠标位置重新定位自己。
  • transientScrollBars : bool  此属性保存滚动条是否为瞬态。当内容滚动时,临时滚动条会出现,当不再需要时,滚动条会消失。默认值是平台相关的。

  

2、SplitView

 SplitView是一个可以水平或垂直放置项目的控件,每个项目之间都有一个可拖动的分隔符。 

在SplitView中总是会有一个(且只有一个)具有 Layout.fillWidth 设置为true(或 Layout.fillHeight,如果方向是Qt.Vertical)。这意味着当其他项目被放置时,项目将得到所有剩余的空间。默认情况下,SplitView的最后一个可见的子元素会有这个设置,但是它可以通过在另一个项上显式地将fillWidth设置为true来改变。 

由于fillWidth项目将自动调整大小以适应额外的空间,显式的分配其宽度和高度属性将被忽略(但 Layout.minimumWidth 和 Layout.maximumWidth 仍然会生效)。其他项目的初始大小应该通过它们的宽度和高度属性来设置。当用户拖动项的拆分器句柄时,任何对项的宽度或高度的绑定赋值都会被打破。

句柄可以属于左侧或顶部的项,也可以属于右侧或底部的项: 

如果fillWidth项在右边:句柄属于左边的项。

如果fillWidth项目在左边:句柄属于右边的项目。

这将再次控制当用户拖动一个句柄时,哪个项目会被调整大小,以及当一个项目被告知隐藏时,哪个句柄会被隐藏。 

SplitView支持在子项目上设置附加布局属性,这意味着你可以为每个子项目设置以下附加属性:

  • Layout.minimumWidth
  • Layout.minimumHeight
  • Layout.maximumWidth
  • Layout.maximumHeight
  • Layout.fillWidth (true for only one child)
  • Layout.fillHeight (true for only one child)

例子: 要创建一个有三个项的SplitView,并让中心项获得多余的空间,可以这样做:

SplitView {
    anchors.fill: parent
    orientation: Qt.Horizontal

    Rectangle {
        width: 200
        Layout.maximumWidth: 400
        color: "lightblue"
        Text {
            text: "View 1"
            anchors.centerIn: parent
        }
    }
    Rectangle {
        id: centerItem
        Layout.minimumWidth: 50
        Layout.fillWidth: true
        color: "lightgray"
        Text {
            text: "View 2"
            anchors.centerIn: parent
        }
    }
    Rectangle {
        width: 200
        color: "lightgreen"
        Text {
            text: "View 3"
            anchors.centerIn: parent
        }
    }
}
  • handleDelegate : Component     此属性保存将在每个子项目之间实例化的委托。在委托内部,以下属性是可用的:
readonly property bool styleData.index Specifies the index of the splitter handle. The handle between the first and the second item will get index 0, the next handle index 1 etc.
readonly property bool styleData.hovered The handle is being hovered.
readonly property bool styleData.pressed The handle is being pressed.
readonly property bool styleData.resizing The handle is being dragged.
  • orientation : int     这个属性保存了SplitView的方向。取值为Qt.Horizontal或Qt.Vertical。默认值为Qt.Horizontal。
  • resizing : bool  当用户通过拖动拆分器句柄来调整任何项的大小时,此属性为真。

    addItem(Item item)

  • void removeItem(Item item)

3、StatckView

  

Properties

    • busy : bool  如果转换正在运行,Busy为真,否则为假。
    • currentItem : Item  堆栈中当前最顶部的项。
    • delegate : StackViewDelegate  推或弹出项时要使用的转换
    • depth : int  当前推入堆栈的项数。
    • initialItem : var  StackView创建时应该显示的第一个项目。initialItem可以接受与StackView.push()的第一个参数相同的值

Methods

    • void clear()  从堆栈中移除所有项。没有动画将被应用。
    • void completeTransition()  立即完成任何正在进行的过渡
    • Item find(function, bool onlySearchLoadedItems)  在堆栈中搜索特定项。函数将被调用堆栈中的每一项(以该项作为参数),直到函数返回true。返回值将是找到的项目。例如:find(function(item, index) {return item。isTheOne})将onlySearchLoadedItems设置为true,表示不加载未加载到内存中的项目
    • Item get(int index, bool dontLoad)  返回堆栈中位于索引位置的项。如果dontLoad为true,该项目将不会被强制加载(如果还没有加载,则返回null)
    • Item pop(Item item)  从堆栈中弹出一个或多个项目。  这个函数也可以接受一个属性列表作为参数- Item StackView::pop(jsobject dict),它可以包含一个或多个以下属性:
      • item如果指定了,所有到(但不包括)Item的项都将弹出。如果item为空,将弹出到(但不包括)第一个项目的所有项目。如果未指定,则只有当前项将弹出。返回弹出的项目
      • immediate: 将此属性设置为true,跳过转换效果。 
    • Item push(Item item)  将项压入堆栈。这个函数也可以接受一个属性列表作为参数- Item StackView::push(jsobject dict),它应该包含一个或多个以下属性:
      • item: 这个属性是必需的,它保存了你想要推送的项目。
      • properties在push时应该分配给项目的QML属性列表。这些属性将在项目被加载时(对于组件或URL),或者当它第一次成为当前项目时(通常是在推送时)被复制到项目中。
      • immediate将此属性设置为true,跳过转换效果。当push一个数组时,您只需要在第一个元素上设置这个属性,就可以立即执行整个操作。
      • replace设置此属性以替换堆栈上的当前项。当push一个数组时,你只需要在第一个元素上设置这个属性,就可以替换堆栈中和数组中一样多的元素。
      • destroyOnPop:设置这个属性来指定当物品弹出堆栈时是否需要销毁它。默认情况下(如果没有指定destroyOnPop), StackView将销毁作为组件或url推送的项目。未被销毁的物品在被推到堆栈之前,将被重新父代到原来的父代,并被隐藏。如果需要设置此属性,请谨慎操作,以免条目泄漏。如果需要一次推送多个项目,还可以推送一个项目数组(属性列表)。转换将只发生在列表中的当前项和最后一项之间。其他项目的加载将推迟到需要时。

  Using StackView in an Application

   在应用程序中使用StackView通常是一个简单的事情,添加StackView作为一个窗口的子窗口。堆栈通常固定在窗口的边缘,除了在顶部或底部,它可能固定在状态栏或其他类似的UI组件。然后可以通过调用堆栈的导航方法来使用堆栈。StackView中显示的第一项是分配给initialItem的项。  Stack.status - Contains the status of the item

4、TabView

  

 TabView为您的应用程序提供了基于选项卡的导航模型。例如,下面的代码片段使用标签来在每个标签页上显示不同颜色的矩形:

TabView {
    Tab {
        title: "Red"
        Rectangle { color: "red" }
    }
    Tab {
        title: "Blue"
        Rectangle { color: "blue" }
    }
    Tab {
        title: "Green"
        Rectangle { color: "green" }
    }
}
  • [read-only] contentItem : Item

          这个属性保存选项卡视图的内容项。被声明为TabView子元素的标签会自动成为TabView的contententitem的父元素。
  • [read-only] count : int  当前的标签数
  • currentIndex : int  当前标签索引
  • frameVisible : bool  标签框围绕内容的可见性
  • tabPosition : int
    • Qt.TopEdge (default)
    • Qt.BottomEdge 
  • QtQuick.Controls.Styles 1.3) readonly property bool styleData.hovered The tab is being hovered. readonly property bool styleData.enabled The tab is enabled. (since QtQuick.Controls.Styles 1.2) readonly property bool styleData.activeFocus The tab button has keyboard focus. readonly property bool styleData.availableWidth The available width for the tabs. readonly property bool styleData.totalWidth The total width of the tabs. (since QtQuick.Controls.Styles 1.2)
    • tabBar : Component  这定义了标签栏的背景。
    • tabOverlap : int  此属性保存单个选项卡按钮之间重叠的数量。

    • tabsAlignment : int  此属性保存选项卡按钮的水平对齐方式。支持的值是:

      • Qt.AlignLeft (default)
      • Qt.AlignHCenter
      • Qt.AlignRight
    • tabsMovable : bool  这个属性保存用户是否可以移动选项卡。默认情况下,不能移动。

    5、SwipeView

      SwipeView提供了一个基于滑动的导航模型。

       

       SwipeView使用一组页面填充。一个页面是可以看到的。用户可以通过向下滑动来在页面之间进行导航。注意,SwipeView本身完全是非可视化的。建议将其与页面显示相结合,给用户一个有多个页面的视觉提示。

      SwipeView {
          id: view
    
          currentIndex: 1
          anchors.fill: parent
    
          Item {
              id: firstPage
          }
          Item {
              id: secondPage
          }
          Item {
              id: thirdPage
          }
      }
    
      PageIndicator {
          id: indicator
    
          count: view.count
          currentIndex: view.currentIndex
    
          anchors.bottom: view.bottom
          anchors.horizontalCenter: parent.horizontalCenter
      }

      如上所示,SwipeView通常使用一组静态页面来填充,这些静态页面被定义为视图的子视图。还可以在运行时动态地添加、插入、移动和删除页面。

    通常不建议在SwipeView中添加过多的页面。但是,当页面的数量变大,或者单个页面相对复杂时,可能希望通过卸载无法访问的页面来释放资源。下面的例子展示了如何使用Loader来保持最多三个页面同时被实例化。

      SwipeView {
          Repeater {
              model: 6
              Loader {
                  active: SwipeView.isCurrentItem || SwipeView.isNextItem || SwipeView.isPreviousItem
                  sourceComponent: Text {
                      text: index
                      Component.onCompleted: console.log("created:", index)
                      Component.onDestruction: console.log("destroyed:", index)
                  }
              }
          }
      }

    注意:SwipeView接管了添加到视图中的项目的几何管理。不支持在项目上使用锚,任何宽度或高度的分配都将被视图覆盖。注意,这只适用于项目的根目录。指定宽度和高度,或为其子节点使用锚定,都可以正常工作。

    • interactive : bool  这个属性描述用户是否可以与SwipeView交互。用户不能滑动非交互式的视图。默认值为true。
    • orientation : enumeration  这个属性保存方向   Qt.Horizontal(default) 和 Qt.Vertical

    • [read-only] SwipeView.index : int  这个附加属性保存SwipeView中每个子项目的索引。它被附加到SwipeView的每个子条目上。
    • [read-only] SwipeView.isCurrentItem : bool  如果此子项是当前项,则此附加属性为真。

    • [read-only] SwipeView.isNextItem : bool  如果此子项是下一项,则此附加属性为真。

    • [read-only] SwipeView.isPreviousItem : bool   如果此子项是前一项,则此附加属性为真。

    • [read-only] SwipeView.view : SwipeView  此附加属性保存管理此子项目的视图。

    5.1 PageIndicator

    PageIndicator用于指示一个包含多个页面的容器中当前活动的页面。PageIndicator由呈现页面的委托项组成。

      Column {
          StackLayout {
              id: stackLayout
    
              Page {
                  // ...
              }
              Page {
                  // ...
              }
              Page {
                  // ...
              }
          }
    
          PageIndicator {
              currentIndex: stackLayout.currentIndex
              count: stackLayout.count
          }
      }
    • count : int  此属性保存页面的数量。

    • currentIndex : int  此属性保存当前页的索引。

    • delegate : Component  此属性保存显示页面的委托。以下属性在每个委托的上下文中是可用的:

      • index : int  The index of the item
      • pressed : bool  Whether the item is pressed
    • interactive : bool  此属性保存控件是否是交互式的。交互式页面指示器对按下做出反应,并自动适当地更改当前索引。缺省值为false。
      SwipeView {
          id: view
          currentIndex: pageIndicator.currentIndex
          anchors.fill: parent
    
          Page {
              title: qsTr("Home")
          }
          Page {
              title: qsTr("Discover")
          }
          Page {
              title: qsTr("Activity")
          }
      }
    
      PageIndicator {
          id: pageIndicator
          interactive: true
          count: view.count
          currentIndex: view.currentIndex
    
          anchors.bottom: parent.bottom
          anchors.horizontalCenter: parent.horizontalCenter
      }

    注意:页面指示器通常是非常小的(为了避免用户从用户界面的实际内容上分心)。它们可能很难点击,而且可能不容易被用户识别为交互式的。由于这些原因,它们最好用于补充主要的导航方法(如SwipeView),而不是取代它们。

    Customizing PageIndicator

    PageIndicator由背景、内容项和委托组成。

      import QtQuick 2.6
      import QtQuick.Controls 2.1
    
      PageIndicator {
          id: control
          count: 5
          currentIndex: 2
    
          delegate: Rectangle {
              implicitWidth: 8
              implicitHeight: 8
    
              radius: width / 2
              color: "#21be2b"
    
              opacity: index === control.currentIndex ? 0.95 : pressed ? 0.7 : 0.45
    
              Behavior on opacity {
                  OpacityAnimator {
                      duration: 100
                  }
              }
          }
      }

    Customizing SwipeView

     SwipeView可以有一个可视的背景项。导航是由内容项实现的。

      import QtQuick 2.6
      import QtQuick.Controls 2.1
    
      SwipeView {
          id: control
    
          background: Rectangle {
              color: "#eeeeee"
          }
      }

    Customizing SwipeDelegate

    SwipeDelegate由6个可视项目组成: background, content item, indicator, swipe. left, swipe. right, and swipe.behind. 

    import QtQuick 2.6
      import QtQuick.Controls 2.1
    
      SwipeDelegate {
          id: control
          text: qsTr("SwipeDelegate")
    
          Component {
              id: component
    
              Rectangle {
                  color: SwipeDelegate.pressed ? "#333" : "#444"
                  width: parent.width
                  height: parent.height
                  clip: true
    
                  Label {
                      text: qsTr("Press me!")
                      color: "#21be2b"
                      anchors.centerIn: parent
                  }
              }
          }
    
          swipe.left: component
          swipe.right: component
    
          contentItem: Text {
              text: control.text
              font: control.font
              color: control.enabled ? (control.down ? "#17a81a" : "#21be2b") : "#bdbebf"
              elide: Text.ElideRight
              verticalAlignment: Text.AlignVCenter
    
              Behavior on x {
                  enabled: !control.down
                  NumberAnimation {
                      easing.type: Easing.InOutCubic
                      duration: 400
                  }
              }
          }
QML