Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct understanding about ScrollBar syntax in QtQuick/QML?

Recently, I used a Scrollbar with a TableView. I referred to QML documentation for ScrollBar and I can see an example:

Flickable {
    focus: true

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

    ScrollBar.vertical: ScrollBar { id: scrollBar }
}

I thought that ScrollBar.vertical is a bool variant, but why there is an object ScrollBar { id: scrollBar } after colon?

Is there any documentation about this syntax?

What is the difference between using

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

    and

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

The same confusion came to me with the code below:

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 }
}

On the line anchors.fill: parent, anchors is lower-case.

like image 567
kurbylee Avatar asked Sep 01 '25 01:09

kurbylee


1 Answers

I thought that ScrollBar.vertical is a bool variant, but why there is an object ScrollBar { id: scrollBar } after the colon?

The answer is simply because ScrollBar.vertical is neither a bool nor a variant but has a type of ScrollBar. This is stated in the documentation.

ScrollBar.vertical : ScrollBar

This property attaches a vertical scroll bar to a Flickable.

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

Note the subheader tells us the type after the colon: ScrollBar.

Is there any documentation about this syntax?

Yes there is. I copied the above from this page.

What is the difference between using [...]

I'll walk through each confusing line of code and label each one with its name.

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

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

//  Grouped Property
anchors.fill: parent

Let's go through these one-by-one.

Attached Properties

Attached properties [...] are mechanisms that enable objects to be annotated with extra properties or signal handlers that are otherwise unavailable to the object. In particular, they allow objects to access properties or signals that are specifically relevant to the individual object.

References to attached properties [...] take the following syntax form:

<AttachingType>.<propertyName>

For example, the ListView type has an attached property ListView.isCurrentItem that is available to each delegate object in a ListView. This can be used by each individual delegate object to determine whether it is the currently selected item in the view:

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

In this case, the name of the attaching type is ListView and the property in question is isCurrentItem, hence the attached property is referred to as ListView.isCurrentItem.

(source)

In our particular case, ScrollBar is the attaching type and vertical is the property.

Keep in mind that there are several differences between ListView.isCurrentItem and ScrollBar.vertical. The former is of type bool while the latter is of type ScrollBar. Additionally, the former is a read-only property, meaning that we can't assign or change it. On the other hand, you can assign to ScrollBar.vertical.

If ListView.isCurrentItem wasn't read-only, we could've assigned it like we did with ScrollBar.vertical.

delegate: Rectangle {
    ListView.isCurrentItem: true
}

But since it is read-only, this raises an error.

Child Objects

This is QML basics right here. Here's an example:

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"
    }
}

Looking back at ScrollBar:

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

This will instantiate a child object ScrollBar but that's it. No added functionality.

Grouped Properties

In some cases properties contain a logical group of sub-property attributes. These sub-property attributes can be assigned to using either the dot notation or group notation.

For example, the Text type has a font group property. Below, the first Text object initializes its font values using dot notation, while the second uses group notation:

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

(source)

Another common example of a grouped property is anchors (as you may have noted).

Don't let the dot notation confuse you. Try to spot a generic difference between the two properties below:

anchors.top
ScrollBar.vertical

The important distinction to make is that properties must begin with a lower-case letter whereas QML types begin with an upper-case letter. With this in mind, we can see that anchors is clearly a property while ScrollBar is a type.


With those out of the way, I think we can try to address one more issue.

Why use attached properties instead of defining ScrollBar as a child object?

Because of better automation. From documentation:

When ScrollBar is attached vertically or horizontally to a Flickable, its geometry and the following properties are automatically set and updated as appropriate:

  • orientation
  • position
  • size
  • active

An attached ScrollBar re-parents itself to the target Flickable. A vertically attached ScrollBar resizes itself to the height of the Flickable, and positions itself to either side of it based on the layout direction. A horizontally attached ScrollBar resizes itself to the width of the Flickable, and positions itself to the bottom.

(source)

This allows you to focus on other things, instead of worrying about the position of the scrollbar.

But sure, instantiating ScrollBar as a child object (non-attached) also has it merits.

It is possible to create an instance of ScrollBar without using the attached property API. This is useful when the behavior of the attached scroll bar is not sufficient or a Flickable is not in use. [...]

When using a non-attached ScrollBar, the following must be done manually:

  • Layout the scroll bar (with the x and y or anchor properties, for example).
  • Set the size and position properties to determine the size and position of the scroll bar in relation to the scrolled item.
  • Set the active property to determine when the scroll bar will be visible.

(source)

like image 61
TrebledJ Avatar answered Sep 02 '25 20:09

TrebledJ