将 qml 中的值动态绑定到转发器创建的对象

Posted

技术标签:

【中文标题】将 qml 中的值动态绑定到转发器创建的对象【英文标题】:Dynamically bind values from qml to repeater created object 【发布时间】:2021-04-22 10:23:07 【问题描述】:

我使用别名属性控制场景中某些元素的位置,如下所示:如果我有一个文件 Foo.qml 包含

Item 
  property alias myprop1: id1
  property alias myprop2: id2
  Node id:id1,...
  Node id:id2,...

在我的 main 上,然后我可以调用

Slider
  id:myslider

foo
  myprop1.x: myslider.value

现在,如果我的 Foo.qml 包含未知数量的属性(假设它们都称为 mypropX)。如果我有 10 个属性,我想创建 10 个滑块,每个属性一个。可以使用上一个答案here中提到的中继器和循环@

Foo
  id:myfoo

Column 
    Repeater 
        id: myrepeater
        delegate: Slider 
            from:0
            to:400
            y: 12*index
        
        Component.onCompleted: 
            let propArray = [];
            for(var prop in myfoo)
                //select only the properties I'm interested in
                //a "onXXXChanged" is created on each properties so I also have to remove it
                if(prop.substring(0, 6)==="myprop" && prop.substring(prop.length-7,prop.length)!=="Changed")
                    propArray.push(prop)
                
            
            myrepeater.model = propArray
        
    


现在的问题是我不知道如何将这 10 个滑块绑定到我的属性。 我尝试在 main 中添加到我的 Foo 实例

Component.onCompleted: 
    let i=0
    for(var prop in myfoo)
        if(prop.substring(0, 6)==="myprop" && prop.substring(prop.length-7,prop.length)!=="Changed")
            //equivalent to myprop1.x: myslider.value when there was no repeater
            myfoo.prop.x = Qt.binding(function() 
                return myrepeater.itemAt(i).value
            )
            i++
        
    

但它会返回

QQmlEngine::setContextForObject(): Object already has a QQmlContext
qrc:/main.qml:145: Error: Cannot assign to non-existent property "prop"

问题是在for循环中,prop是一个字符串。我也不确定在执行 onCompleted 的那一刻,转发器已经创建了所有的滑块。

我可以使用 QML 类型 Bindings,它采用目标 (myrepeater.itemAt(i).value) 和属性名称作为 字符串,但我不知道如何调用 Bindings 类型来自 javascript

【问题讨论】:

你可以使用 [] 运算符,所以myfoo[prop] 如果我没看错的话 解决了non-existent property 问题。现在有第一条错误消息:QQmlEngine::setContextForObject(): Object already has a QQmlContext 仍然存在 我无法从给定的代码中检查。你知道它发生在哪条线上吗? 你也可以尝试使用Binding对象 原来这就是我想做的。所有绑定对象,没有用于绑定的 javascript。我的中继器的委托是一个包含滑块 + 绑定对象的项目Binding target: myfoo[modelData]; property: "width"; value: slider.value 【参考方案1】:

您可以使用 [] 运算符从 myfoo 读取属性,如前所述,我将在委托中使用 Binding 对象:

import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

Window 
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Item 
        id: myfoo

        property int myprop_upper_threshold
        onMyprop_upper_thresholdChanged: console.log("upper_threshold", myprop_upper_threshold)
        property int myprop_lower_threshold
        onMyprop_lower_thresholdChanged: console.log("lower_threshold", myprop_lower_threshold)
    

    ColumnLayout 

        Repeater 
            id: myrepeater
            delegate: Slider 
                id: myslider
                from: 0
                to: 400

                Text 
                    text: modelData
                

                Binding 
                    target: myfoo
                    property: modelData
                    value: myslider.value
                
            

            Component.onCompleted: 
                let propArray = [];
                for(var prop in myfoo)
                
                    //select only the properties I'm interested in
                    //a "onXXXChanged" is created on each properties so I also have to remove it
                    if(prop.substring(0, 6)==="myprop" && prop.substring(prop.length-7,prop.length)!=="Changed")
                    
                        propArray.push(prop)
                    
                
                myrepeater.model = propArray
            
        
    

【讨论】:

以上是关于将 qml 中的值动态绑定到转发器创建的对象的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 从 QML 中动态创建的列表中访问数据

JQjq动态绑定事件.on()解绑事件off()

如何在 QML 中的同一事件之后创建/销毁动态对象?

jQuery动态创建的元素为啥不能绑定事件

为啥动态组件创建中的属性绑定不起作用?

检查/访问 QML 中动态创建的对象