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. Strange behavior with dynamically removed objects

Strange behavior with dynamically removed objects

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
2 Posts 2 Posters 202 Views
  • 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.
  • R Offline
    R Offline
    r3d9u11
    wrote on last edited by r3d9u11
    #1

    Hello. I'm noted one situation:

    OwnLabel.qml

    import QtQuick 2.12
    import QtQuick.Controls 2.12
    Label { text: "Own Label" }
    

    main.qml:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.12
    import QtQuick.Layouts 1.12
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        property var __ownLabelComponent: Qt.createComponent("OwnLabel.qml")
    
        ColumnLayout {
    
            RowLayout {
                Button {
                    text: qsTr("Add")
                    onClicked: {
                        var ownLabel = __ownLabelComponent.createObject(labelsContainter);
                        ownLabel.text += labelsContainter.children.length;
                    }
                }
    
                Button {
                    text: qsTr("Remove")
                    onClicked: {
                        if (labelsContainter.children.length > 0)
                            labelsContainter.children[0].destroy();
    
                        console.log(labelsContainter.children.length);
                    }
                }
    
                Button {
                    text: qsTr("Clear & Add New 3")
                    onClicked: {
                        for (var i = 0; i < labelsContainter.children.length; ++i)
                            labelsContainter.children[i].destroy();
    
                        for (var j = 0; j < 3; ++j) {
                            var ownLabel = __ownLabelComponent.createObject(labelsContainter);
                            ownLabel.text += labelsContainter.children.length;
                        }
    
                        console.log(labelsContainter.children.length);
                    }
                }
            }
    
            ColumnLayout {
                id: labelsContainter
            }
    
        }
    }
    

    If you try to click Add, then Remove and then Add, again, it will work correctly:

    • output "3,2,1,0"
    • 3 elements will be displayed with titles "Own Label 1", "Own Label 2", "Own Label 3"

    But, if you try to click "Clean & Add 3" instead of "Clean", you will see:

    • output, that container have 6 child elements
    • 3 elements will be displayed with titles "Own Label 4", "Own Label 5", "Own Label 6"

    So, children.length will not be refreshed until current UI's event (button onClick) has not been done.
    (I suspect that faced this situation because QML runs in one thread and all event are staying in one queue)

    Is there any way to update ".length" property immediately (to use it further in current procedure)?

    Thanks!

    1 Reply Last reply
    0
    • GrecKoG Offline
      GrecKoG Offline
      GrecKo
      Qt Champions 2018
      wrote on last edited by
      #2

      My advise (as most of the time on the forum :P ), would be to not do things like you are doing.
      Manipulating UI items is not very mainenable and flexible. You should act on your data instead.

      I don't really know what is your use case, but most of the time you should avoid using Qt.createObject or Qt.createComponent and let view/models class handle the instantiation of your dynamic objects.

      In your example, you could use a Repeater with a model (an int, a js array, a ListModel, ...). I rewrote it with a ListModel :

      import QtQuick 2.12
      import QtQuick.Window 2.12
      import QtQuick.Controls 2.12
      import QtQuick.Layouts 1.12
      
      Window {
          visible: true
          width: 640
          height: 480
          title: qsTr("Hello World")
      
          ListModel {
              id: listModel
          }
      
          ColumnLayout {
      
              RowLayout {
                  Button {
                      text: qsTr("Add")
                      onClicked: listModel.append({text: listModel.count + 1})
                  }
      
                  Button {
                      text: qsTr("Remove")
                      onClicked: {
                          if (listModel.count > 0)
                              listModel.remove(0);
                      }
                  }
      
                  Button {
                      text: qsTr("Clear & Add New 3")
                      onClicked: {
                          listModel.clear();
                          for (var i = 0; i < 3; ++i) {
                              listModel.append({text: listModel.count + 1})
                          }
                      }
                  }
              }
      
              ColumnLayout {
                  Repeater {
                      model: listModel
                      Label { // you can replace that with OwnLabel
                          text: "My text: %1, my index: %2".arg(model.text).arg(model.index)
                      }
                  }
              }
          }
      }
      
      1 Reply Last reply
      4

      • Login

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