如何从属性为模型设置值?

huangapple go评论154阅读模式
英文:

How to set value to a model from the property?

问题

我想根据操作系统向`ListView`模型添加不同的文件:
```qml
ApplicationWindow {
    id: window
    readonly property string settingsFile: (Qt.platform.os === "android") ? "qrc:/huts/qml/settings-android.qml" : "qrc:/huts/qml/settings.qml"
    Drawer {
        ListView {
            id: listView
            model: ListModel {
            ListElement { title: qsTr("Port Settings"); source: window.settingsFile }
            ListElement { title: qsTr("Terminal"); source: "qrc:/huts/qml/terminal.qml" }
            }
        ...
        }
    ...

但是我收到了一个错误:
>"ListElement: cannot use script for property value"
如何实现这个目标?


<details>
<summary>英文:</summary>

I want to add different files to the `ListView` model depending on the OS:

ApplicationWindow {
id: window
readonly property string settingsFile: (Qt.platform.os === "android") ? "qrc:/huts/qml/settings-android.qml" : "qrc:/huts/qml/settings.qml"
Drawer {
ListView {
id: listView
model: ListModel {
ListElement { title: qsTr("Port Settings"); source: window.settingsFile }
ListElement { title: qsTr("Terminal"); source: "qrc:/huts/qml/terminal.qml" }
}
...
}
...

But I get an error: 
&gt;&quot;ListElement: cannot use script for property value&quot;

How can this goal be achieved?

</details>


# 答案1
**得分**: 1

最简单的方法是在javascript函数中追加项目。在追加时可以使用脚本值。

ListModel
{
    id: listModel

    Component.onCompleted:
    {
        listModel.append({ 
            title: qsTr("端口设置"),
            source: window.settingsFile
        });
        listModel.append({ 
            title: qsTr("终端"),
            source: "qrc:/huts/qml/terminal.qml"
        });
    }
}
英文:

The easiest way to do this is to append items in a javascript function. You can use script values when appending.

ListModel
{
    id: listModel

    Component.onCompleted:
    {
        listModel.append({ 
            title: qsTr(&quot;Port Settings&quot;),
            source: window.settingsFile
        });
        listModel.append({ 
            title: qsTr(&quot;Terminal&quot;),
            source: &quot;qrc:/huts/qml/terminal.qml&quot;
        });
    }
}

答案2

得分: 1

对于你的问题中涉及到的Android部分,你可以利用+android文件选择器:

huts/qml/terminal.qml
huts/qml/+android/terminal.qml

也就是说,当你在QML中使用"huts/qml/terminal.qml"时,QML会在Android上自动加载专门针对Android的文件,而在其他情况下则加载默认的文件。

至于你的ListModel,在QML中不允许使用表达式进行初始化,因此无法在声明时访问变量或使用qsTr()。如其他答案所建议,你可以在代码中实现。你可以通过声明一个JavaScript对象并从该对象初始化你的ListModel来在声明性和命令性之间取得更好的平衡,例如:

ListView {
    id: listView
    model: ListModel {
        property var _data: [
            { title: qsTr("Port Settings"), source: "huts/qml/settings.qml" },
            { title: qsTr("Terminal"), source: "huts/qml/terminal.qml" }
        ]
        Component.onCompleted: { for (let obj of _data) append(obj) }
    }
    delegate: ItemDelegate { text: title }
}

注意:在你的QML中使用qrc:/可能并不是必要的,因为你的主应用程序很可能已经是一个qrc:资源了,所以只需使用相对引用来指向你的主文件所在的位置即可。因此,使用"huts/qml/settings.qml"而不是"qrc:/huts/qml/settings.qml"即可。

参考资料:

英文:

For the Android part of your question, you should take the opportunity to use +android file selectors:

huts/qml/terminal.qml
huts/qml/+android/terminal.qml

i.e. when you use &quot;huts/qml/terminal.qml&quot; in QML, QML will automatically load the Android specialized file on Android and load the other by default.

As to your ListModel, QML does not permit you to initialize it using expressions, so accessing variables or using qsTr() both are not permitted declaratively. As suggested by the other answer you can do it in code. You can strike a higher balance between declarative and imperative, by declaring a JavaScript object and initialize your ListModel from the object, e.g.

    ListView {
        id: listView
        model: ListModel {
            property var _data: [
                { title: qsTr(&quot;Port Settings&quot;), source: &quot;huts/qml/settings.qml&quot; },
                { title: qsTr(&quot;Terminal&quot;), source: &quot;huts/qml/terminal.qml&quot; }
            ]
            Component.onCompleted: { for (let obj of _data) append(obj) }
        }
        delegate: ItemDelegate { text: title }
    }

N.B. the use of "qrc:/" in your QML may not be necessary, since your main application is probably a "qrc:" resource already, so, it is enough to use a relative reference to where your main file is. So "huts/qml/settings.qml" instead of "qrc:/huts/qml/settings.qml"

References:

huangapple
  • 本文由 发表于 2023年8月10日 23:33:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76877254.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定