ReferenceError: down is not defined in SpinBox QML

ReferenceError: down is not defined in SpinBox QML

我指的是 https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-spinbox 并复制粘贴了相同的代码,但我收到以下错误:

ReferenceError: down is not defined and ReferenceError: up 未定义。

代码:

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

我应该包括任何额外的导入吗?

不,您不需要包含任何额外的导入。只是,这个例子使用了不好的做法,在这里你明白为什么了:

这是示例的代码(简化为仅修改 up.indicator):

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

这里我们将 SpinBox 作为文件的根元素。

现在让我们谈谈名称解析。
有问题的行标有 // <---*

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

向上从何而来?首先它会在对象中查找使用它的地方 - RectangleRectangle 没有 up-属性,因此它将继续并在文件的根节点中查找,即 SpinBox - 这有一个 up-属性,也有 pressed.

的值

当我们尝试使用它(错误的方式)时,情况看起来有所不同。让我们添加一个 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
            }
        }
    }
}

同一行 - 将尝试在 Rectangle 中查找 up,失败并继续查找文件根节点,现在是 ApplicationWindow。在这里它再次失败。由于 ApplicationWindow 未在另一个文件中使用,可能存在另一个文件根节点,因此搜索将结束并最终失败。

出了什么问题?该示例的作者错过了应用良好实践以始终使用完全限定标识符的方法:id.property.... 就像他在定义 Rectangle.[=35 的 x 值时所做的那样=]

换行:

color: up.pressed ? [...]

至:

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

将解决问题,因为我们现在明确声明在哪里寻找 属性 up.

重要的一课

  • 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