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

Posted

技术标签:

【中文标题】如何在 QML 中的同一事件之后创建/销毁动态对象?【英文标题】:How to create/destroy dynamic objects after the same event in QML? 【发布时间】:2016-03-04 17:37:41 【问题描述】:

我有一个 GridLayout dynamicLayout,它具有动态创建/销毁的元素。当我单击按钮 myButton 时会发生创建/销毁,为此我还提供了下面的代码。

GridLayout 
    id: dynamicLayout
    anchors.fill: parent

    Component 
        id: imageComponent
        Image 
            visible: true
            function deleteImage() 
                console.log("destroying image")
                destroy()
            
        
    


    Button 
    id: myButton
    visible: true
    x: 200
    y: 200

    onClicked: 
        createImageObjects();
    



function createImageObjects() 
    if (imageComponent.status == Component.Ready)
        finishCreation();
    else
        imageComponent.statusChanged.connect(finishCreation);


function finishCreation() 
    if (imageComponent.status == Component.Ready) 
        for (var i= 0; i < 3; i++) 
            var object = imageComponent.createObject(dynamicLayout, "width": 100, "height": 100, "source": FILE_PATH);
            if (object == null) 
                // Error Handling
                console.log("Error creating object");
             else 
               myButton.clicked.connect(object.deleteImage)
            
        
     else if (imageComponent.status == Component.Error) 
        // Error Handling
        console.log("Error loading component:", imageComponent.errorString());
    

所以我打算在单击按钮时将 3 个新图像添加到布局中,同时删除旧的 3 个图像。但是,首先创建较新的 3 个映像,然后立即销毁所有 6 个映像。 (我收到 6 条带有相同点击事件的“破坏图像”消息)

如何推迟连接到下一个点击事件?

【问题讨论】:

【参考方案1】:

首先,不需要使用两步对象创建方法 - 只有当您从远程源加载组件时才需要,这是异步完成的。您实际上并不需要从本地存储加载组件,当您的 Component 在源代码中嵌入时更是如此。

其次,由于多个信号连接的堆叠方式,当你按下按钮时,你执行第一个连接,这是创建函数,它增加了更多的连接,所以它们在第一个连接之后执行,这导致立即删除刚刚创建的对象。没有一种很好的方式可以说“直到下次再处理这些连接”。您可以使用计时器来延迟连接,但除了笨拙之外,这也为错误打开了空间。

你的设计很糟糕。相反,您应该选择简单而实用的东西。例如,有一个property var images : [] - 一个 JS 数组,您可以在其中存储对现有图像的引用。因此,每次按下按钮时 - 删除现有图像(如果有),然后创建新图像并将它们推送到阵列中。您还可以通过这种方式节省连接和事件处理。

【讨论】:

我实际上是 javascript 新手,想将对象保存在数组中,但不确定是否可行。那么在我的情况下你是怎么做的呢? 是的,这是可能的。但是,您的代码的目的是什么?您正在创建 3 个没有来源的图像,什么也没显示?您可能甚至不需要手动创建对象,您可以使用模型和中继器。 我没有提供第一部分,但在第一次点击之前,createImages 被调用一次,所以我在第一次点击时替换了 3 张图片 您的图片没有图片来源。创建不显示图像的图像元素的目的是什么? 你应该解释你真正想要达到的目标是什么,因为可能有比你正在采取的更好的方法。这里的实际目标是什么?

以上是关于如何在 QML 中的同一事件之后创建/销毁动态对象?的主要内容,如果未能解决你的问题,请参考以下文章

QML:获取 QObject 父级

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

如何将动态创建的 qmlcomponent 对象绑定到另一个动态创建的 qmlcomponent 对象的属性?

QML:从动态 MouseArea 中“窃取”事件

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

如何为 QML 创建一个动态的全局主题?