问题
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