Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to create Q_PROPERTY 'alias' in C++.
Forum Updated to NodeBB v4.3 + New Features

How to create Q_PROPERTY 'alias' in C++.

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 1.3k 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.
  • L Offline
    L Offline
    LScott
    wrote on last edited by LScott
    #1

    In QML, it is simple to create an alias of a property:

    property int number: 1
    property alias numeral: number
    

    However, I cannot find a method of doing the same thing from C++ that matches the subtleties of the QML engine.

    The most obvious thing that comes to mind is:

    Q_PROPERTY(int number READ GetNumber WRITE SetNumber NOTIFY NumberChanged)
    Q_PROPERTY(int numeral READ GetNumber WRITE SetNumber NOTIFY NumberChanged)
    

    or perhaps:

    Q_PROPERTY(int number MEMBER _number)
    Q_PROPERTY(int numeral MEMBER _number)
    

    However the problem arises that a new binding or constant value assigned to the 'numeral' property will not break an older binding assigned to the 'number' property.

    An example:

    number: myNumber
    
    ...
    
    numeral: 3
    
    /* 'numeral' now becomes 3, until 'myNumber' changes,
        at which point the 'myNumber' binding takes over.
        This wouldn't happen with a qml property alias.*/
    

    Looking in the documentation, I cannot find a simple (or, for that matter, complicated) method of breaking property bindings from C++.

    Any ideas?

    kshegunovK 1 Reply Last reply
    0
    • L LScott

      In QML, it is simple to create an alias of a property:

      property int number: 1
      property alias numeral: number
      

      However, I cannot find a method of doing the same thing from C++ that matches the subtleties of the QML engine.

      The most obvious thing that comes to mind is:

      Q_PROPERTY(int number READ GetNumber WRITE SetNumber NOTIFY NumberChanged)
      Q_PROPERTY(int numeral READ GetNumber WRITE SetNumber NOTIFY NumberChanged)
      

      or perhaps:

      Q_PROPERTY(int number MEMBER _number)
      Q_PROPERTY(int numeral MEMBER _number)
      

      However the problem arises that a new binding or constant value assigned to the 'numeral' property will not break an older binding assigned to the 'number' property.

      An example:

      number: myNumber
      
      ...
      
      numeral: 3
      
      /* 'numeral' now becomes 3, until 'myNumber' changes,
          at which point the 'myNumber' binding takes over.
          This wouldn't happen with a qml property alias.*/
      

      Looking in the documentation, I cannot find a simple (or, for that matter, complicated) method of breaking property bindings from C++.

      Any ideas?

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #2

      @LScott said in How to create Q_PROPERTY 'alias' in C++.:

      However, I cannot find a method of doing the same thing from C++ that matches the subtleties of the QML engine.

      I don't believe there's any. As far as I understand the two properties are distinct, even if they use the same getter, setter and notifier. Why don't you use what QML provides already?

      Looking in the documentation, I cannot find a simple (or, for that matter, complicated) method of breaking property bindings from C++.

      There's no "property binding" as such here, what you have is two properties that share the same piece of data, which isn't exactly the same as having an alias. They just overwrite each other depending on who was last written.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      1
      • L Offline
        L Offline
        LScott
        wrote on last edited by
        #3

        There's no "property binding" as such here

        Right, no binding on the C++ side, but the QML/javascript generates a binding with the line:

        number: myNumber
        

        assuming that 'myNumber' is a notifiable property (or replaced with an expression), right?

        I suppose there is no way for the C++ to know about the binding, it's just getting the setter called as far as it's concerned? I was hoping there might be some way to break the javascript binding from C++ with QMetaProperty or something.

        Why don't you use what QML provides already?

        I certainly could, but it seems messy to keep different property definitions in different places, I'd rather avoid it.

        Thanks for the response :)

        kshegunovK J.HilkJ 2 Replies Last reply
        1
        • L LScott

          There's no "property binding" as such here

          Right, no binding on the C++ side, but the QML/javascript generates a binding with the line:

          number: myNumber
          

          assuming that 'myNumber' is a notifiable property (or replaced with an expression), right?

          I suppose there is no way for the C++ to know about the binding, it's just getting the setter called as far as it's concerned? I was hoping there might be some way to break the javascript binding from C++ with QMetaProperty or something.

          Why don't you use what QML provides already?

          I certainly could, but it seems messy to keep different property definitions in different places, I'd rather avoid it.

          Thanks for the response :)

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @LScott said in How to create Q_PROPERTY 'alias' in C++.:

          I suppose there is no way for the C++ to know about the binding

          Not as far as I know.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0
          • L LScott

            There's no "property binding" as such here

            Right, no binding on the C++ side, but the QML/javascript generates a binding with the line:

            number: myNumber
            

            assuming that 'myNumber' is a notifiable property (or replaced with an expression), right?

            I suppose there is no way for the C++ to know about the binding, it's just getting the setter called as far as it's concerned? I was hoping there might be some way to break the javascript binding from C++ with QMetaProperty or something.

            Why don't you use what QML provides already?

            I certainly could, but it seems messy to keep different property definitions in different places, I'd rather avoid it.

            Thanks for the response :)

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #5

            @LScott
            you could simply emit the changed signal multiple times after each other.

            The QML engine should detect a "binding loop" and break the binding itself.
            Hacky, but it should work.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            1
            • L Offline
              L Offline
              LScott
              wrote on last edited by
              #6

              Finally came back to this problem (testers wouldn't stop bugging me about it).

              Found a potential solution!

              QQmlProperty::write(QObject*, const QString& name)

              It doesn't seem to be documented, but calling this function seems to break any existing QML bindings on the specified property. So I just create a separate WRITE function for my aliased property:

              Q_PROPERTY(int number READ GetNumber WRITE SetNumber NOTIFY NumberChanged)
              Q_PROPERTY(int numeral READ GetNumber WRITE OverwriteNumber NOTIFY NumberChanged)
              
              void OverwriteNumber(const int value)
              {
                  QQmlProperty p(this, "number");
              
                  p.write(value);
              }
              

              Seems to work for me.
              Basically gets around the problem of C++ being unaware of the binding by writing to the property through the QML context, I guess. It's probably much slower than calling the setter directly, so probably not ideal for properties that change frequently, but it will suffice for my purposes.

              1 Reply Last reply
              1

              • Login

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