【问题标题】:How do you assign a QML Item to a component property in QML and then use that object inside the component?如何将 QML 项目分配给 QML 中的组件属性,然后在组件内使用该对象?
【发布时间】:2011-02-16 19:47:05
【问题描述】:

我正在尝试创建一个 QML 对象,该对象的作用类似于其他对象的包装器。这是我的 QML 文件 (Container.qml):

Item {
    property string label
    property Item control

    Row {
        Label {
            text: label
        }

        // Not sure how to display the control assigned to the control property
    }
}

我想做的事情(在我使用这个组件的 QML 中)是这样的:

Container {
    label: "My Label"
    control: Textbox {
        text: "My Value"
    }
}

当输入该 QML 时,结果(在界面中)应该类似于该 QML 的输出:

Item {
    Row {
        Label {
            text: "My Label"
        }
        Textbox {
            text: "My Value"
        }
    }
}

这可能吗?当我尝试这样做时,在将项目分配给控件属性时,我得到“无法将对象分配给属性”。我搜索了 Qt 论坛并无情地用谷歌搜索了这个,但没有成功。如果有人知道答案,将不胜感激。

谢谢

杰克

【问题讨论】:

    标签: properties qml


    【解决方案1】:

    有更好的解决方案:

    /* MyObject.qml */
    
    Rectangle {
        default property alias data /* name can be any */ : inner_space.data
    
        /* ... You can put other elements here ... */
        Item {
           id: inner_space
    
           /* ... Params ... */
        }
        /* ... You can put other elements here ... */
    }
    

    现在我们可以为所欲为!

    /* main.qml */
    
    Rectangle {
        MyObject {
            Button {
                 /* ... */
            }
        }
    }
    

    感谢用户bobbaluba 建议使用data 属性而不是children

    【讨论】:

    【解决方案2】:

    您可以使用Loader 元素动态加载项目,然后将'control' 属性设置为直接引用加载器的sourceComponent 属性的alias

    所以您的 Container.qml 可能如下所示:

    Item {
        property string label
        property alias control : loader.sourceComponent
    
        width: 200; height: 200
    
        Row {
            Label { text: label }
            Loader { id: loader }
        }
    }
    

    现在,当您将图形项分配给“控件”属性时,加载器将自动显示它。

    【讨论】:

    • 哇,Loader 对象看起来很棒!希望我很久以前就知道这一点!这是一个更优雅的解决方案。感谢分享!
    【解决方案3】:

    您可以使用自定义属性为其他项目创建容器:

    Item
    {
        id: root
    
        property list<Item> rectList: [
            Rectangle
            {
                parent: root
            },
            Rectangle
            {
                parent: root
            },
            Rectangle
            {
                parent: root
            },
            Rectangle
            {
                parent: root
            }
        ]
    }
    

    请注意,矩形项的父项是手动设置的,因此它们将是容器的可视子项。

    您可以将它们评估为 javascript 数组

    for ( var i = 0; i < root.rectList.length; i++ )
    {
       var rect = root.rectList[i];
       rect.visible = true;
    }
    

    rect.rectList[1].visible = false;
    

    【讨论】:

    • 这确实有效——我从没想过我们可以在 QML 中使用“模板列表”——你在哪里找到的?这是记录在任何地方 ???
    • 我记得没有具体记录。它源于 javascript 与 QObject 的设计和集成。我必须通过反复试验来了解有关指定父母的细节
    【解决方案4】:

    已经使用 QML 大约一个月了,恐怕真的不知道该怎么做。

    最好的计划是找出控件(在您的示例中为Textbox)可能的所有可能事物,为您的行中的每个组件创建一个实例,并在您的Item 上设置相应的状态。然后状态会根据需要负责使所需的组件可见或不可见。

    编辑

    只是想。 (还没有尝试过,但试一试!)在您的ItemComponent.onCompleted: 处理程序中,尝试调用control.createObject(rowID) 其中rowID 是您的id 对象的id,(您想要成为control 的父级)。

    【讨论】:

    • 感谢您的回复!该解决方案(据我所知)会起作用,但并不理想。所有这些额外的隐藏控件只是为了呈现一个控件……似乎是一种浪费。我会继续插电。如果我找到任何东西,我一定会回帖。
    • 这当然看起来应该有效。我误解了有关动态创建对象的文档。你的简短解释为我澄清了这一点。我仍然收到"cannot assign object to property" 错误。这没有意义,因为我认识你can assign Items to properties。例如,矩形接受一个渐变(不是项目,我知道,而是一个对象)。我认为您的答案是正确的,我只是不明白为什么这不起作用! :) 谢谢你的帮助!如果您有更多见解,请告诉我!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 2019-08-09
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    相关资源
    最近更新 更多