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

青春壹個敷衍的年華 提交于 2021-02-08 10:20:47

问题


I have a GridLayout dynamicLayout which has dynamically created/destroyed elements. Create/destroy happens when I click a Button myButton, for which I also provided the code below.

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());
    }
}

So what I intend to do is to add 3 new images to the layout when the button is clicked and while deleting the older 3 images. However, the newer 3 images are created first and after that all of the 6 images are destroyed at once. (I get 6 'destroying images' message with the same click event)

How can I postpone the connecting to the next click event?


回答1:


First of all, there is no need to use the two step object creation method - it is only necessary when you are loading components from remote sources, which is done asynchronously. You don't really need that for loading components from local storage, even less so when your Component is in-line in the source.

Second, due to the way multiple signal connections stack, when you press your button, you execute the first connection which is the creation function, which adds more connections, so they are executed after the first connection, which leads to the immediate deletion of the objects that were just created. There isn't a nice way to say "don't process those connections until next time". You could use a timer to delay the connections, but aside from clumsy, that also opens room for bugs.

Your design is plain out bad. Instead you should go for something simple and functional. For example, have a property var images : [] - a JS array in which you store references to the existing images. So each time you press the button - delete the existing images if any, then create the new ones and push them into the array. You will also save on connections and event handling this way.



来源:https://stackoverflow.com/questions/35802547/how-to-create-destroy-dynamic-objects-after-the-same-event-in-qml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!