Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Forward QML property binding in C++

    QML and Qt Quick
    2
    5
    232
    Loading More Posts
    • 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
      Asperamanca last edited by Asperamanca

      I'd like to write a C++ adapter class that can be used in QML like this:

      Image
      {
         id: closeImage
         source: resource.svg(":/icons/close", closeImage.width, closeImage.height).Url
      }
      

      "resource" is a QObject with a Q_INVOKABLE function named "svg".
      The function accepts a resource path (QString) and a desired width and height.

          Q_INVOKABLE QVariant svg(const QString& resourcePath,
                                   const QVariant& width,
                                   const QVariant& height);
      

      It returns an intermediate QObject, which has a Property called "Url" with getter and notifier signal.

      class SvgResourceEntry : public QObject
      {
          Q_OBJECT
          QML_ANONYMOUS
          
          Q_PROPERTY(QUrl Url READ getUrl NOTIFY notifyUrlChanged)
          //...
      

      Now, if the width and height (parameters 2 and 3) change, I'd like the C++ adapter to know. In this case, I would generate a new image of the correct size, and change the returned Url (probably asynchronously with time delay, but still). Through property binding, the Image component would load the changed image.

      For this to work, I not only need the current width and height values, but actually the properties, so I can connect to the respective change signals.

      Problem is, if I pass closeImage.width and height like seen above, on the C++ side I only see a double value (QVariant-type 6), not a QQmlProperty object or something like it.

      So how could I achieve this property binding into C++?

      1 Reply Last reply Reply Quote 0
      • fcarney
        fcarney last edited by

        @Asperamanca said in Forward QML property binding in C++:

        source: resource.svg(":/icons/close", closeImage.width, closeImage.height).Url

        source: resource.svg(":/icons/close", closeImage.width, closeImage.height).Url
        

        This would get reevaluated when the width or height changes. Just make sure the Url that it produces is slightly different each time. That way closeImage will update itself. I don't know the details of your SvgResourceEntry. What does the Url return? Is this a generated resource? Can you change the name.

        Another possibility is to blank out the Url. Then do a call later in the C++ code to update the Url. This should trigger Image to re-fetch the image.

        C++ is a perfectly valid school of magic.

        A 1 Reply Last reply Reply Quote 0
        • A
          Asperamanca @fcarney last edited by

          @fcarney said in Forward QML property binding in C++:

          source: resource.svg(":/icons/close", closeImage.width, closeImage.height).Url
          

          This would get reevaluated when the width or height changes.

          Really? Even if resource.svg is a Q_INVOKABLE, and not a property? That has serious performance implications in other use cases...

          What does the Url return? Is this a generated resource? Can you change the name.

          I intend to use QQuickImageProvider, so I can return what I want.

          Sounds like an approach worth to try. Thanks!

          1 Reply Last reply Reply Quote 0
          • fcarney
            fcarney last edited by fcarney

            @Asperamanca said in Forward QML property binding in C++:

            Really? Even if resource.svg is a Q_INVOKABLE, and not a property? That has serious performance implications in other use cases...

            What performance implications? Any expression that has a value change can be reevaluated.

            Now, if the width and height (parameters 2 and 3) change, I'd like the C++ adapter to know. In this case, I would generate a new image of the correct size, and change the returned Url

            Isn't this reevaluation what you want to happen?

            This is what will happen when the inputs change. You can test with a Q_INVOKABLE, but I would expect the same behavior.

                property int countint: 0
                property int changing: changeCall(countint)
            
                function changeCall(input){
                    console.log("changeCall", countint)
            
                    return input+1
                }
            
                onChangingChanged: console.log("changing", changing)
            
                Timer {
                    interval: 1000
                    running: true
                    repeat: true
            
                    onTriggered: {
                        countint = countint + 1
                    }
                }
            

            C++ is a perfectly valid school of magic.

            1 Reply Last reply Reply Quote 0
            • A
              Asperamanca last edited by

              Yes, it does make sense, when I think a little about it. And if you know that is how it works, it can actually simplify some code.

              Thanks!

              1 Reply Last reply Reply Quote 0
              • First post
                Last post