Solved Destroying dynamically created objects in a loop
-
I have simplified my problem to this simple code. I have a
Button
in my main window. When it is clicked, it will dynamically create 3 objects of typeMyDialog
. When user clicks on theOK
button of the dialog, aclosed
signal is emitted. I connect to this signal in the main window and try to destroy the object. I noticed that when I try to destory the second and third dialogs, I get this message in the consoleqrc:/main.qml:19: TypeError: Property 'destroy' of object TypeError: Type error is not a function
I think this error is indicating that I am trying to free the same memory location multiple times. I am wondering how I can fix this issue. I know I can have
MyDialog
destroy itself but I want to do it inmain.qml
. Thanks in advance for your helpHere is my code
// main.qml import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Window 2.15 Window { width: 640 height: 480 visible: true Button { id: button anchors.centerIn: parent text: "Generate 3 Message dialogs" onClicked: { var component = Qt.createComponent("qrc:/MyDialog.qml") for(var ii = 0; ii < 3; ++ii) { var object = component.createObject(button) // Connecting to the closed signal of MyDialog object.closed.connect(()=>{object.destroy()}) } } } }
and
// MyDialog.qml import QtQuick 2.15 import QtQuick.Dialogs 1.3 Item { id: root signal closed() MessageDialog { text: "I am a dialog" visible: true standardButtons: StandardButton.Ok // closed() signal is emitted once the user hits Ok onAccepted: root.closed() } }
-
@aShahba said in Destroying dynamically created objects in a loop:
I have simplified my problem to this simple code. I have a
Button
in my main window. When it is clicked, it will dynamically create 3 objects of typeMyDialog
. When user clicks on theOK
button of the dialog, aclosed
signal is emitted. I connect to this signal in the main window and try to destroy the object. I noticed that when I try to destory the second and third dialogs, I get this message in the consoleqrc:/main.qml:19: TypeError: Property 'destroy' of object TypeError: Type error is not a function
I think this error is indicating that I am trying to free the same memory location multiple times.
That is what is happening. The root of the problem is that
var object
is captured in each arrow function, rather thanobject
's value at the time the closure is defined. -
You dont need to do a connection in main.qml, just call destroy() in the object when the buttom is clicked:
onAccepted: root.destroy()
-
@johngod I know how to have the dialog do self-destruction when
accepted
signal is emitted. As mentioned in the post, I want to do it inmain.qml
though.On a sidenote, the problem with self-destruction is that it is only valid if the item is created dynamically. As you can imagine, it is not guaranteed that
MyDialog
is always created dynamically. -
@aShahba said in Destroying dynamically created objects in a loop:
I have simplified my problem to this simple code. I have a
Button
in my main window. When it is clicked, it will dynamically create 3 objects of typeMyDialog
. When user clicks on theOK
button of the dialog, aclosed
signal is emitted. I connect to this signal in the main window and try to destroy the object. I noticed that when I try to destory the second and third dialogs, I get this message in the consoleqrc:/main.qml:19: TypeError: Property 'destroy' of object TypeError: Type error is not a function
I think this error is indicating that I am trying to free the same memory location multiple times.
That is what is happening. The root of the problem is that
var object
is captured in each arrow function, rather thanobject
's value at the time the closure is defined. -
@aShahba said in Destroying dynamically created objects in a loop:
@johngod I know how to have the dialog do self-destruction when
accepted
signal is emitted. As mentioned in the post, I want to do it inmain.qml
though.On a sidenote, the problem with self-destruction is that it is only valid if the item is created dynamically. As you can imagine, it is not guaranteed that
MyDialog
is always created dynamically.Inline components are useful for doing this in a more declarative fashion.
Button { Component { id: inlineComponent MyDialog { onClosed: this.destroy() } } onClicked: inlineComponent.createObject(this) }