ListElement 字段作为属性?

发布于 2024-12-08 02:08:54 字数 611 浏览 2 评论 0原文

这是我的代码:

import QtQuick 1.0

ListModel {
    property real firstValue: 2
    property real secondValue: 3
    property real thirdValue: 1
    id: leftGrid
    ListElement {
        icon: "Images/1.png"
        value: leftGrid.firstValue
    }
    ListElement {
        icon: "2.png"
        value: -1
    }
    ListElement {
        icon: "3.png"
        value: leftGrid.secondValue
    }
    ListElement {
        icon: "4.png"
        value: leftGrid.thirdValue
    }
}

这给了我错误:

ListElement: cannot use script for property value

我应该做什么?

Here is my code :

import QtQuick 1.0

ListModel {
    property real firstValue: 2
    property real secondValue: 3
    property real thirdValue: 1
    id: leftGrid
    ListElement {
        icon: "Images/1.png"
        value: leftGrid.firstValue
    }
    ListElement {
        icon: "2.png"
        value: -1
    }
    ListElement {
        icon: "3.png"
        value: leftGrid.secondValue
    }
    ListElement {
        icon: "4.png"
        value: leftGrid.thirdValue
    }
}

This gives me the error:

ListElement: cannot use script for property value

What should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

疯了 2024-12-15 02:08:54

ListElement 字段不是传统意义上的 QML 属性,而是其父 ListModel 中的角色。所以属性绑定在这种情况下不起作用。这就是为什么您会收到 QML 错误:“ListElement:无法使用脚本获取属性值”,这有点令人困惑。

尽管已向 Qt 团队提交了修复此问题的请求,但迄今为止尚未实施任何解决方案。

同时,如果您不想实现自己的 C++ 类来处理列表模型,正如 @Luca Carlon 所建议的那样,我已经尝试过一个有效的 QML 解决方法/解决方案。要点是:

  • 当ListModel的字段需要引用其他属性时,不要使用ListModel。
  • 相反,使用 ListModel.append() 进行模型初始化,并使用 ListModel.setProperty() 进行模型更新。在这两个方法调用的参数列表中,可以将角色分配给其他属性,这相当于属性绑定。

将此 QML 解决方法/解决方案应用于原始示例代码将产生以下修订后的示例代码:

import QtQuick 2.0

Rectangle {
    width: 400
    height: 200

    ListModel {
        property real firstValue: 2
        property real secondValue: 3
        property real thirdValue: 1
        id: leftGrid

    // The commented-out code belowwon't work:
    // ListElement:Cannot use script for property value.
    //        ListElement {
    //            icon: "Images/1.png"
    //            value: leftGrid.firstValue
    //        }
    //        ListElement {
    //            icon: "2.png"
    //            value: -1
    //        }
    //        ListElement {
    //            icon: "3.png"
    //            value: leftGrid.secondValue
    //        }
    //        ListElement {
    //            icon: "4.png"
    //            value: leftGrid.thirdValue
    //        }
    // QML workaround/solution to the above code:

        // 1. Initialize the list model:
        property bool completed: false
        Component.onCompleted: {
            append({"icon": "Images/1.png", value: leftGrid.firstValue});
            append({"icon": "2.png", value: -1});
            append({"icon": "3.png", value: leftGrid.secondValue});
            append({"icon": "4.png", value: leftGrid.thirdValue});
            completed = true;
        }

        // 2. Update the list model:
        onFirstValueChanged: {
            if(completed) setProperty(0, "value", leftGrid.firstValue);
        }
        onSecondValueChanged: {
            if(completed) setProperty(2, "value", leftGrid.secondValue);
        }
        onThirdValueChanged: {
            if(completed) setProperty(3, "value", leftGrid.thirdValue);
        }
    }
}

如果您运行上述修订后的示例代码(例如使用 Qt 5.5.0),您将不再收到 QML 错误。当然,我也不喜欢这个 QML 解决方法/解决方案。

The ListElement fields are not QML properties in the traditional sense, but rather the roles in its parent ListModel. So property binding does not work in this case. That is why you get QML error: "ListElement: cannot use script for property value", which is a bit confusing.

Although there has been a request submitted to the Qt Team to have this fixed, so far no resolution has been implemented.

In the meantime, if you do not want to implement your own C++ class to handle the list model, as suggested by @Luca Carlon, there is a QML workaround/solution I have tried which works. The main points are:

  • Do not use ListModel when its fields need to reference other properties.
  • Instead, use ListModel.append() for the model initialization, and use ListModel.setProperty() for the model updating. Inside the argument list of these 2 method calls, the roles can be assigned to the other properties, which is equivalent to property binding.

Applying this QML workaround/solution to your original example code will result in the following revised example code:

import QtQuick 2.0

Rectangle {
    width: 400
    height: 200

    ListModel {
        property real firstValue: 2
        property real secondValue: 3
        property real thirdValue: 1
        id: leftGrid

    // The commented-out code belowwon't work:
    // ListElement:Cannot use script for property value.
    //        ListElement {
    //            icon: "Images/1.png"
    //            value: leftGrid.firstValue
    //        }
    //        ListElement {
    //            icon: "2.png"
    //            value: -1
    //        }
    //        ListElement {
    //            icon: "3.png"
    //            value: leftGrid.secondValue
    //        }
    //        ListElement {
    //            icon: "4.png"
    //            value: leftGrid.thirdValue
    //        }
    // QML workaround/solution to the above code:

        // 1. Initialize the list model:
        property bool completed: false
        Component.onCompleted: {
            append({"icon": "Images/1.png", value: leftGrid.firstValue});
            append({"icon": "2.png", value: -1});
            append({"icon": "3.png", value: leftGrid.secondValue});
            append({"icon": "4.png", value: leftGrid.thirdValue});
            completed = true;
        }

        // 2. Update the list model:
        onFirstValueChanged: {
            if(completed) setProperty(0, "value", leftGrid.firstValue);
        }
        onSecondValueChanged: {
            if(completed) setProperty(2, "value", leftGrid.secondValue);
        }
        onThirdValueChanged: {
            if(completed) setProperty(3, "value", leftGrid.thirdValue);
        }
    }
}

If you run the above revised example code, using Qt 5.5.0 for example, you will no longer get the QML error. Sure, I do not like this QML workaround/solution either.

转瞬即逝 2024-12-15 02:08:54

我也有这个问题。考虑采用此处报告的解决方案之一:https://bugreports.qt.io/browse/ QTBUG-16289 根据您的 Qt 版本进行解释。

我个人更喜欢用 C++ 实现该模型。阅读此内容: http:// /cdumez.blogspot.com/2010/11/how-to-use-c-list-model-in-qml.html

I had this problem as well. Consider adopting one of the solutions reported in here: https://bugreports.qt.io/browse/QTBUG-16289 according to your version of Qt as explained.

I personally prefer to implement the model in C++. Read this: http://cdumez.blogspot.com/2010/11/how-to-use-c-list-model-in-qml.html.

蓝色星空 2024-12-15 02:08:54

我的解决方案是不使用 ListElement 作为模型项:

property real firstValue: 2
...

ComboBox
{
    model: [
        { text: firstValue, value: firstValue },
        { text: secondValue, value: secondValue },
        { text: thirdValue, value: thirdValue }
    ]

    ...
}

My solution to this is not using ListElement as model item:

property real firstValue: 2
...

ComboBox
{
    model: [
        { text: firstValue, value: firstValue },
        { text: secondValue, value: secondValue },
        { text: thirdValue, value: thirdValue }
    ]

    ...
}
清旖 2024-12-15 02:08:54

如果您尝试从 C++ 引用未使用 Q_ENUM 注册的枚举,也可能会发生此错误。

This error can also occur if you try to reference an enum from C++ that is not registered with Q_ENUM.

雨轻弹 2024-12-15 02:08:54

这也可能是另一种解决方法,因为 "从 Qt 5.11 ListElement 也开始允许将函数声明分配给角色。这允许定义具有可调用操作的 ListElements。”

import QtQuick

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    Rectangle {
        anchors.fill: parent

        ListModel {
            id: fruitModel
            property real appleValue: 2.45
            property real orangeValue: 3.25
            property real bananaValue: 1.95
            ListElement {
                name: "Apple"
                // cost: 2.45
                // cost: fluidModel.appleValue // Error: ListElement: cannot use script for property value
                cost: function(newCost = 2.45){// value 2.45 could be stored in a persistent setting
                    return (fruitModel.appleValue = newCost);
                }
            }
            ListElement {
                name: "Orange"
                // cost: 3.25
                // cost: fluidModel.orangeValue // Error: ListElement: cannot use script for property value
                cost: function(newCost = 3.25){
                    return (fruitModel.orangeValue = newCost);
                }
            }
            ListElement {
                name: "Banana"
                // cost: 1.95
                // cost: fluidModel.bananaValue // Error: ListElement: cannot use script for property value
                cost: function(newCost = 1.95){
                    return (fruitModel.bananaValue = newCost);
                }
            }
        }

        Component {
            id: fruitDelegate
            Row {
                spacing: 10
                Text { text: name }
                // Text { text: '
 + cost } // if value
                Text { text: '
 + cost() } // if function
            }
        }

        ListView {
            anchors.fill: parent
            model: fruitModel
            delegate: fruitDelegate
        }
    }
}

This also could be another workaround since "Beginning with Qt 5.11 ListElement also allows assigning a function declaration to a role. This allows the definition of ListElements with callable actions."

import QtQuick

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    Rectangle {
        anchors.fill: parent

        ListModel {
            id: fruitModel
            property real appleValue: 2.45
            property real orangeValue: 3.25
            property real bananaValue: 1.95
            ListElement {
                name: "Apple"
                // cost: 2.45
                // cost: fluidModel.appleValue // Error: ListElement: cannot use script for property value
                cost: function(newCost = 2.45){// value 2.45 could be stored in a persistent setting
                    return (fruitModel.appleValue = newCost);
                }
            }
            ListElement {
                name: "Orange"
                // cost: 3.25
                // cost: fluidModel.orangeValue // Error: ListElement: cannot use script for property value
                cost: function(newCost = 3.25){
                    return (fruitModel.orangeValue = newCost);
                }
            }
            ListElement {
                name: "Banana"
                // cost: 1.95
                // cost: fluidModel.bananaValue // Error: ListElement: cannot use script for property value
                cost: function(newCost = 1.95){
                    return (fruitModel.bananaValue = newCost);
                }
            }
        }

        Component {
            id: fruitDelegate
            Row {
                spacing: 10
                Text { text: name }
                // Text { text: '
 + cost } // if value
                Text { text: '
 + cost() } // if function
            }
        }

        ListView {
            anchors.fill: parent
            model: fruitModel
            delegate: fruitDelegate
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文