Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Destroying dynamically created objects in a loop
Forum Updated to NodeBB v4.3 + New Features

Destroying dynamically created objects in a loop

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 3 Posters 694 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    aShahba
    wrote on 2 Jun 2021, 18:10 last edited by
    #1

    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 the OK button of the dialog, a closed 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 console

    qrc:/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 in main.qml. Thanks in advance for your help

    Here 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()
        }
    }
    
    J 1 Reply Last reply 3 Jun 2021, 04:33
    0
    • A aShahba
      2 Jun 2021, 18:10

      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 the OK button of the dialog, a closed 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 console

      qrc:/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 in main.qml. Thanks in advance for your help

      Here 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()
          }
      }
      
      J Offline
      J Offline
      jeremy_k
      wrote on 3 Jun 2021, 04:33 last edited by
      #4

      @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 the OK button of the dialog, a closed 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 console

      qrc:/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 than object's value at the time the closure is defined.

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#creating_closures_in_loops_a_common_mistake

      Asking a question about code? http://eel.is/iso-c++/testcase/

      1 Reply Last reply
      1
      • J Offline
        J Offline
        johngod
        wrote on 2 Jun 2021, 23:30 last edited by
        #2

        You dont need to do a connection in main.qml, just call destroy() in the object when the buttom is clicked:

        onAccepted: root.destroy()
        
        A 1 Reply Last reply 3 Jun 2021, 01:01
        0
        • J johngod
          2 Jun 2021, 23:30

          You dont need to do a connection in main.qml, just call destroy() in the object when the buttom is clicked:

          onAccepted: root.destroy()
          
          A Offline
          A Offline
          aShahba
          wrote on 3 Jun 2021, 01:01 last edited by aShahba 6 Mar 2021, 01:02
          #3

          @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 in main.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.

          J 1 Reply Last reply 3 Jun 2021, 04:44
          0
          • A aShahba
            2 Jun 2021, 18:10

            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 the OK button of the dialog, a closed 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 console

            qrc:/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 in main.qml. Thanks in advance for your help

            Here 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()
                }
            }
            
            J Offline
            J Offline
            jeremy_k
            wrote on 3 Jun 2021, 04:33 last edited by
            #4

            @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 the OK button of the dialog, a closed 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 console

            qrc:/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 than object's value at the time the closure is defined.

            https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#creating_closures_in_loops_a_common_mistake

            Asking a question about code? http://eel.is/iso-c++/testcase/

            1 Reply Last reply
            1
            • A aShahba
              3 Jun 2021, 01:01

              @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 in main.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.

              J Offline
              J Offline
              jeremy_k
              wrote on 3 Jun 2021, 04:44 last edited by
              #5

              @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 in main.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)
              }
              

              Asking a question about code? http://eel.is/iso-c++/testcase/

              1 Reply Last reply
              0

              1/5

              2 Jun 2021, 18:10

              • Login

              • Login or register to search.
              1 out of 5
              • First post
                1/5
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved