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. Pushing to StackView with property bindings
Forum Updated to NodeBB v4.3 + New Features

Pushing to StackView with property bindings

Scheduled Pinned Locked Moved Solved QML and Qt Quick
7 Posts 3 Posters 3.6k 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.
  • MrBoltonM Offline
    MrBoltonM Offline
    MrBolton
    wrote on last edited by MrBolton
    #1

    Hello all,

    I've got a problem when trying to push a component to a StackView and I hope someone could clarify this.

    In a QML slot I push a custom component to a StackView like this:

    var deviceList = Qt.createComponent("DeviceGroups.qml");
    if(deviceList.status === Component.Ready) {
        stack.push(deviceList, { "model": modelManager.locationContent } );
    }
    

    DeviceGroups.qml is a customized ListView and the above code works as expected, hence the model is properly set. However it seems that no property bindings are created when setting the model like this. The ListView does not get updated when the model does. I confirmed that the relevant signal is being emitted and received in QML but the ListView doesn't care. To confirm this I tried the same with a simple text element which I update via a QML Timer like this:

    Text {
         id: testText
         text: "This is a test"
    }
    Timer {
         interval: 5000
         onTriggered: testText.text = testText.text + "."
         running: true
         repeat: true
    }
    
    [...]
    
    onClicked: {
        var deviceList = Qt.createComponent("Test.qml");
        if(deviceList.status === Component.Ready) {
            stack.push(deviceList, { "text": testText.text } );
        }
    }
    

    Test.qml is a simple Text item so the resulting view should be updated every time the timer triggers, or am I missing something?

    Thanks for any help
    Tobi

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by A Former User
      #2

      Hi! I didn't fully get what you're doing there but are you aware of the fact that you're only creating a component without actually instantiating an object from it? I guess your code should more look like this:

      var component = Qt.createComponent("Button.qml"); // only a component so far
      if (component.status == Component.Ready) {
        var button = component.createObject(container); // now we have an instance
        button.color = "red";
      }
      
      MrBoltonM 1 Reply Last reply
      0
      • ? A Former User

        Hi! I didn't fully get what you're doing there but are you aware of the fact that you're only creating a component without actually instantiating an object from it? I guess your code should more look like this:

        var component = Qt.createComponent("Button.qml"); // only a component so far
        if (component.status == Component.Ready) {
          var button = component.createObject(container); // now we have an instance
          button.color = "red";
        }
        
        MrBoltonM Offline
        MrBoltonM Offline
        MrBolton
        wrote on last edited by
        #3

        @Wieland said:

        Hi! I didn't fully get what you're doing there but are you aware of the fact that you're only creating a component without actually instantiating an object from it?

        Thanks for the tip. But is there any difference in pushing a component to the StackView or pushing an actual instance?

        To elaborate further on my problem, if I change your example a bit it might get clearer:

        var component = Qt.createComponent("Button.qml"); // only a component so far
        if (component.status == Component.Ready) {
          var button = component.createObject(container); // now we have an instance
          button.color = somePropertyThatChangesOverTime;
          stack.push(button);
        }
        

        My problem with this is that the color of the button that is pushed onto the StackView would not get updated.
        Is this a bug or do I have to create the property binding myself (if yes, how) ?

        Thanks in advance!

        1 Reply Last reply
        0
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by A Former User
          #4

          @MrBolton said:

          But is there any difference in pushing a component to the StackView or pushing an actual instance?

          A "component" is only like a class definition in C++. See Creating a Component Dynamically.

          @MrBolton said:

          My problem with this is that the color of the button that is pushed onto the StackView would not get updated.
          Is this a bug or do I have to create the property binding myself (if yes, how) ?

          It's not a bug, and yes, here you have to create the binding yourself. That's because button.color = someThingThatChanges is just a Javascript assignment. It only once copies the current value of someThingThatChanges to button.color at exactly this point of execution. If you want to create a binding from Javascript code you can do it like this:

          button.color = Qt.binding(function() { return someThingThatChanges});
          
          1 Reply Last reply
          0
          • jpnurmiJ Offline
            jpnurmiJ Offline
            jpnurmi
            wrote on last edited by
            #5

            StackView::push() accepts Items, Components, and URLs. If you want to push a QML file, the most straight-forward way is to pass the URL and let StackView handle the rest.

            Passing properties to StackView::push() works identically with Component::createObject(). If you want to create a binding, you'll need to use Qt.binding().

            stack.push(Qt.resolvedUrl("Button.qml"), {color: Qt.binding(function() { return foo.bar })})
            

            We'll add a note about the property bindings to the docs.

            ? 1 Reply Last reply
            1
            • jpnurmiJ jpnurmi

              StackView::push() accepts Items, Components, and URLs. If you want to push a QML file, the most straight-forward way is to pass the URL and let StackView handle the rest.

              Passing properties to StackView::push() works identically with Component::createObject(). If you want to create a binding, you'll need to use Qt.binding().

              stack.push(Qt.resolvedUrl("Button.qml"), {color: Qt.binding(function() { return foo.bar })})
              

              We'll add a note about the property bindings to the docs.

              ? Offline
              ? Offline
              A Former User
              wrote on last edited by
              #6

              @jpnurmi Thx for clarifying this! :)

              1 Reply Last reply
              0
              • MrBoltonM Offline
                MrBoltonM Offline
                MrBolton
                wrote on last edited by
                #7

                Thank you all! As soon as I created the binding, it works like a charm!
                And thanks to the explanation on component creation, it's now much less code! :)

                1 Reply Last reply
                0

                • Login

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