如何在 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 数组,您在其中存储对现有图像的引用。因此,每次按下按钮 - 删除现有图像(如果有),然后创建新图像并将它们推送到数组中。您还将以这种方式节省连接和事件处理。
我有一个 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 数组,您在其中存储对现有图像的引用。因此,每次按下按钮 - 删除现有图像(如果有),然后创建新图像并将它们推送到数组中。您还将以这种方式节省连接和事件处理。