这是我的代码:
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
我该怎么办?
ListElement
字段不是传统意义上的 QML 属性,而是其父级 ListModel
中的角色。所以属性绑定在这种情况下不起作用。这就是为什么你会收到 QML 错误:“ListElement:无法使用脚本作为属性值”,这有点令人困惑。
尽管已向 Qt 团队提交了修复此问题的请求,但迄今为止尚未实施任何解决方案。
同时,如果您不想实现自己的 C++ 类来处理列表模型,正如 @Luca Carlon 所建议的那样,我已经尝试过一种有效的 QML 解决方法/解决方案。要点是:
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 解决方法/解决方案。
我也遇到这个问题了。考虑采用此处报告的解决方案之一:https://bugreports.qt.io/browse/QTBUG-16289 根据您所解释的 Qt 版本。
我个人更喜欢用C++实现该模型。阅读此内容:http://cdumez.blogspot.com/2010/11/how-to-use-c-list-model-in-qml.html.
我的解决方案是不使用
ListElement
作为模型项:
property real firstValue: 2
...
ComboBox
{
model: [
{ text: firstValue, value: firstValue },
{ text: secondValue, value: secondValue },
{ text: thirdValue, value: thirdValue }
]
...
}
如果您尝试从 C++ 引用未使用 Q_ENUM 注册的枚举,也可能会发生此错误。
这也可能是另一种解决方法,因为“从 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
}
}
}