如何在 QML 中的同一事件后 create/destroy 动态对象?

How to create/destroy dynamic objects after the same event in QML?

我有一个 GridLayout dynamicLayout,它具有动态的 created/destroyed 元素。 Create/destroy 当我单击按钮 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 'destroying images' 条具有相同点击事件的消息)

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

首先,没有必要使用两步对象创建方法——只有当您从远程源加载组件时才有必要,这是异步完成的。从本地存储加载组件时,您真的不需要它,当您的 Component 在源代码中内联时更不需要。

其次,由于多个信号连接堆栈的方式,当您按下按钮时,您执行第一个连接,即创建功能,它会添加更多连接,因此它们在第一个连接之后执行,这导致立即删除刚刚创建的对象。 "don't process those connections until next time" 没有好的表达方式。您可以使用计时器来延迟连接,但除了笨拙之外,这也为错误打开了空间。

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