对QtQuick / QML中的ScrollBar语法的正确理解是什么?

时间:2019-05-08 01:55:02

标签: qt syntax qml scrollbar

最近,我使用了ScrollbarTableView。我提到 QML documentation for ScrollBar,我可以看到一个示例:

Flickable {
    focus: true

    Keys.onUpPressed: scrollBar.decrease()
    Keys.onDownPressed: scrollBar.increase()

    ScrollBar.vertical: ScrollBar { id: scrollBar }
}

我以为ScrollBar.vertical是bool的变体,但是为什么在冒号后面有一个对象ScrollBar { id: scrollBar }

是否有关于此语法的文档?

使用之间有什么区别

  1. ScrollBar.vertical: ScrollBar { id: scrollBar }
    

  2. ScrollBar { id: scrollBar; orientation: Qt.Vertical }
    

下面的代码也给我带来了困惑:

Flickable {
    anchors.fill: parent

    contentWidth: parent.width * 2
    contentHeight: parent.height * 2

    ScrollBar.horizontal: ScrollBar { id: hbar; active: vbar.active }
    ScrollBar.vertical: ScrollBar { id: vbar; active: hbar.active }
}

anchors.fill: parent行上,anchors是小写字母。

1 个答案:

答案 0 :(得分:0)

我以为ScrollBar.vertical是bool的变体,但是为什么在冒号后面有一个对象ScrollBar { id: scrollBar }

答案仅仅是因为ScrollBar.vertical既不是布尔型变量也不是变体,而是类型为ScrollBar。这在文档中有说明。

  

ScrollBar.vertical : ScrollBar

     

此属性将垂直滚动条附加到Flickable。

Flickable {
    contentHeight: 2000
    ScrollBar.vertical: ScrollBar { }
}

请注意,子标题会告诉我们冒号后面的类型:ScrollBar

是否有关于此语法的文档?

是的。我从this page复制了上面的内容。

使用[...]

有什么区别

我将遍历每行令人困惑的代码行,并为每行代码添加名称。

ScrollBar.vertical: ScrollBar { id: scrollBar }
//  Attached Property

ScrollBar { id: scrollBar; orientation: Qt.Vertical }
//  Child Object

anchors.fill: parent
//  Grouped Property

让我们一一讲解。

附加属性

  

附加属性 [...]是一种机制,可以通过额外的属性或信号处理程序对对象进行注释,否则这些属性将对对象不可用。特别是,它们允许对象访问与单个对象特别相关的属性或信号。

     

对附加属性的引用[...]采用以下语法形式:

<AttachingType>.<propertyName>
     

例如,ListView类型具有一个附加属性ListView.isCurrentItemListView中的每个委托对象都可以使用该属性。每个单独的委托对象都可以使用它来确定它是否是视图中当前选中的项目:

import QtQuick 2.0

ListView {
    width: 240; height: 320
    model: 3
    delegate: Rectangle {
        width: 100; height: 30
        color: ListView.isCurrentItem ? "red" : "yellow"
    }
}
     

在这种情况下,附加类型的名称为ListView,相关属性为isCurrentItem,因此附加属性称为ListView.isCurrentItem

(source)

在我们的特定情况下,ScrollBar附加类型,而vertical属性

请记住,ListView.isCurrentItemScrollBar.vertical之间存在一些差异。前者的类型为bool,而后者的类型为ScrollBar。此外,前者是read-only属性,这意味着我们无法分配或更改它。另一方面,您可以分配给ScrollBar.vertical

如果ListView.isCurrentItem 不是只读的,我们可以像使用ScrollBar.vertical那样分配它。

delegate: Rectangle {
    ListView.isCurrentItem: true
}

但是由于它是只读的,所以会引发错误。

子对象

这是QML基础知识。这是一个示例:

ApplicationWindow {
    visible: true
    width: 800; height: 600

    //  child object of ApplicationWindow
    Rectangle { 
        width: 200; height: 200
        color: "red"

        //  child object of Rectangle
        Text { text: "Hello World" }
    }

    //  child object of ApplicationWindow
    Rectangle {
        x: 400
        width: 200; height: 200
        color: "blue"
    }
}

回顾ScrollBar

Flickable {
    ScrollBar { id: scrollBar; orientation: Qt.Vertical }
}

这将实例化子对象ScrollBar,仅此而已。没有添加功能。

分组属性

  

在某些情况下,属性包含逻辑上的子属性属性组。可以使用点符号或组符号将这些子属性属性分配给它们。

     

例如,Text类型具有字体组属性。下面,第一个Text对象使用点表示法初始化其font值,而第二个对象使用组表示法:

Text {
    //dot notation
    font.pixelSize: 12
    font.b: true
}

Text {
    //group notation
    font { pixelSize: 12; b: true }
}

(source)

分组属性的另一个常见示例是anchors(您可能已经注意到)。

不要让点符号使您感到困惑。尝试找出以下两个属性之间的一般差异:

anchors.top
ScrollBar.vertical

重要的区别在于,属性必须以小写字母开头,而 QML类型必须以大写字母开头。考虑到这一点,我们可以看到anchors显然是一个属性,而ScrollBar是一种类型。


有了这些建议,我认为我们可以尝试解决另一个问题。

为什么使用附加属性而不是将ScrollBar定义为子对象?

由于更好​​的自动化。来自文档:

  

ScrollBar垂直或水平附加到Flickable时,其几何形状和以下属性将自动设置并适当更新:

     
      
  • 方向
  •   
  • 位置
  •   
  • 大小
  •   
  • 活动
  •   
     

附加的ScrollBar将自己重新定位到目标Flickable。垂直连接的ScrollBar会将其自身调整为Flickable的高度,并根据布局方向将其放置在ScrollBar的任一侧。水平附着的Flickable会将其大小调整为ScrollBar的宽度,并将其放置在底部。

(source)

这使您可以专注于其他事情,而不必担心滚动条的位置。

但是可以肯定的是,将ScrollBar实例化为子对象(未附加)也有其优点。

  

可以在不使用附加属性API的情况下创建Flickable的实例。当所附滚动条的行为不充分或未使用{{1}}时,此功能很有用。 [...]

     

使用独立的ScrollBar时,必须手动完成以下操作:

     
      
  • 布局滚动条(例如,使用x和y或anchor属性)。
  •   
  • 设置大小和位置属性,以确定滚动条相对于滚动项的大小和位置。
  •   
  • 设置active属性以确定滚动条何时可见。
  •   

(source)