简体   繁体   English

如何在QML中将QML项目分配给组件属性,然后在组件内部使用该对象?

[英]How do you assign a QML Item to a component property in QML and then use that object inside the component?

I'm trying to create a QML object that acts like a wrapper for other objects. 我正在尝试创建一个QML对象,其作用类似于其他对象的包装器。 Here's my QML file (Container.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
    }
}

What I would like to do (in my QML that consumes this component) is something like this: 我想做什么(在我的QML中使用这个组件)是这样的:

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

When fed that QML the result (in the interface) should be something resembling the output from this QML: 当输入QML时,结果(在界面中)应该类似于此QML的输出:

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

Is this possible? 这可能吗? When I try to do this I get "cannot assign object to property" when assigning an Item to the control property. 当我尝试这样做时,在将一个Item分配给control属性时,我得到“无法将对象分配给属性”。 I've searched the Qt forums and Googled this mercilessly, but no success. 我搜索了Qt论坛并无情地搜索了这个,但没有成功。 If anybody knows the answer it would be greatly appreciated. 如果有人知道答案,我将不胜感激。

Thanks 谢谢

Jack 插口

There is much better solution: 有更好的解决方案:

/* 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 ... */
}

And now we can do all we want! 现在我们可以做我们想要的一切!

/* main.qml */

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

Thanks to user bobbaluba for suggesting to use the data property rather than children . 感谢用户bobbaluba建议使用data属性而不是children

You can dynamically load items using the Loader element, and then set the 'control' property to be an alias that directly refers to the loader's sourceComponent property. 您可以使用Loader元素动态加载项目,然后将'control'属性设置为直接引用加载器的sourceComponent属性的别名

So your Container.qml could look like this: 所以你的Container.qml看起来像这样:

Item {
    property string label
    property alias control : loader.sourceComponent

    width: 200; height: 200

    Row {
        Label { text: label }
        Loader { id: loader }
    }
}

Now when you assign a graphical item to the 'control' property, it will automatically be displayed by the Loader. 现在,当您将图形项目分配给“control”属性时,Loader将自动显示该图形项。

You can create a container for other items using a custom property: 您可以使用自定义属性为其他项创建容器:

Item
{
    id: root

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

Note that the parent of the Rectangle Items is set manually so they will be visual children of the container. 请注意,矩形项的父项是手动设置的,因此它们将是容器的可视子项。

You can assess them as a javascript array 您可以将它们评估为javascript数组

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

or 要么

rect.rectList[1].visible = false;

Been using QML for about a month now, no idea really how to do this I'm afraid. 现在使用QML大约一个月了,我不知道怎么做到这一点我很害怕。

Best plan is to figure out all possible things that the control ( Textbox in your example) could be, create an instance of each component in your row, and set a corresponding state on your Item . 最好的计划是找出控件(示例中的Textbox )可能存在的所有可能的东西,创建行中每个组件的实例,并在Item上设置相应的状态。 The state would then take care of making the desired component visible or invisible as appropriate. 然后,州将根据需要使所需组件可见或不可见。

Edit 编辑

Just thought. 只是觉得。 (Haven't tried this but give it a go!) In your Item 's Component.onCompleted: handler, try calling control.createObject(rowID) where rowID is an id for your Row object, (which you want to be the parent of control ). (还没试过,但试一试!)在你的ItemComponent.onCompleted: handler中,尝试调用control.createObject(rowID) ,其中rowID是你的Row对象的id ,(你想成为父对象) control )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM