pra7
pra7

Reputation: 884

ReferenceError: down is not defined in SpinBox QML

I am referring to https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-spinbox and copy pasted the same code, But i am getting following errors:

ReferenceError: down is not defined and ReferenceError: up is not defined.

Code:

import QtQuick 2.6
import QtQuick.Controls 2.1

    SpinBox {
            id: control
            value: 50
            editable: true

            contentItem: TextInput {
                z: 2
                text: control.textFromValue(control.value, control.locale)

                font: control.font
                color: "#21be2b"
                selectionColor: "#21be2b"
                selectedTextColor: "#ffffff"
                horizontalAlignment: Qt.AlignHCenter
                verticalAlignment: Qt.AlignVCenter

                readOnly: !control.editable
                validator: control.validator
                inputMethodHints: Qt.ImhFormattedNumbersOnly
            }

            up.indicator: Rectangle {
                x: control.mirrored ? 0 : parent.width - width
                height: parent.height
                implicitWidth: 40
                implicitHeight: 40
                color: up.pressed ? "#e4e4e4" : "#f6f6f6"
                border.color: enabled ? "#21be2b" : "#bdbebf"

                Text {
                    text: "+"
                    font.pixelSize: control.font.pixelSize * 2
                    color: "#21be2b"
                    anchors.fill: parent
                    fontSizeMode: Text.Fit
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                }
            }

            down.indicator: Rectangle {
                x: control.mirrored ? parent.width - width : 0
                height: parent.height
                implicitWidth: 40
                implicitHeight: 40
                color: down.pressed ? "#e4e4e4" : "#f6f6f6"
                border.color: enabled ? "#21be2b" : "#bdbebf"

                Text {
                    text: "-"
                    font.pixelSize: control.font.pixelSize * 2
                    color: "#21be2b"
                    anchors.fill: parent
                    fontSizeMode: Text.Fit
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                }
            }

            background: Rectangle {
                implicitWidth: 140
                border.color: "#bdbebf"
            }
        }

Should i include any additional imports ?

Upvotes: 0

Views: 741

Answers (1)

derM
derM

Reputation: 13691

No, you don't need to include any additional imports. It is just, that the example uses bad practice and here you see why:

This is the (reduced to modifying only the up.indicator) code of the example:

import QtQuick 2.6
import QtQuick.Controls 2.0

SpinBox {
    id: control
    value: 50
    editable: true

    up.indicator: Rectangle {
        x: control.mirrored ? 0 : parent.width - width
        height: parent.height
        implicitWidth: 40
        implicitHeight: 40
        color: up.pressed ? "#e4e4e4" : "#f6f6f6"  // <---*
        border.color: enabled ? "#21be2b" : "#bdbebf"

        Text {
            text: "+"
            font.pixelSize: control.font.pixelSize * 2
            color: "#21be2b"
            anchors.fill: parent
            fontSizeMode: Text.Fit
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
        }
    }
}

Here we have the SpinBox as the root element of the file.

Now lets talk about name resolution.
The line in question is marked with a // <---*

control: up.pressed ? "..." : "..."

Where does up come from? At first it will look in the object, where it is used - the Rectangle. The Rectangle has no up-property, so it will continue and looking in the root node of the file, which is the SpinBox - this has a up-property, which also has a value for pressed.

The situation looks different, when we try to use it (the wrong way). Let's add a ApplicationWindow:

import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0

ApplicationWindow {
    id: window

    width: 800
    height: 600
    visible: true

    SpinBox {
        id: control
        value: 50
        editable: true

        up.indicator: Rectangle {
            x: control.mirrored ? 0 : parent.width - width
            height: parent.height
            implicitWidth: 40
            implicitHeight: 40
            color: up.pressed ? "#e4e4e4" : "#f6f6f6"
            border.color: enabled ? "#21be2b" : "#bdbebf"

            Text {
                text: "+"
                font.pixelSize: control.font.pixelSize * 2
                color: "#21be2b"
                anchors.fill: parent
                fontSizeMode: Text.Fit
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
            }
        }
    }
}

Same line - will try to look up up in the Rectangle, fails and continues to the files root node, which is now an ApplicationWindow. Here it fails again. As the ApplicationWindow is not used in another file, where another files root node might exist, the search will end and finally fail.

What went wrong? The writer of the example missed the to apply the good practice to always use fully qualified identifiers: id.property.... as he did for example to define the x-value of the Rectangle.

Changing the line:

color: up.pressed ? [...]

to:

color: control.up.pressed ? [...]

will solve the problem, as we now explicitly declare where to look for the property up.

Important Lesson

  • Names are not resolved by going from child to parent, but always from child to the files root node and so on, until it can't go on
  • Always identify the object either explicitly by parent (but be aware, that you might not know what exactly the parent is. So ideally only for anchors and position) or by the objects's id

Upvotes: 3

Related Questions