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. Integrating QML and C++
QtWS25 Last Chance

Integrating QML and C++

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 4 Posters 1.5k 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.
  • tomyT Offline
    tomyT Offline
    tomy
    wrote on last edited by
    #1

    Hi all,

    As the first step for being familiar with the technique integrating QML and C++ I went for this example.
    I ran it and I have some questions:

    • Why do we need a Q_PROPERTY macro there? Yeah, I know that it's said that it declares a property that could be accessed from QML. But we have two functions for both reading and writing to the data member. (userName) We could have declared a data member named, say, userName, and haven't declared a a Q_PROPERTY macro seemingly.

    • The program does almost nothing and just gets texts! Emitting the signal won't work either there.

    jsulmJ J.HilkJ 2 Replies Last reply
    0
    • tomyT tomy

      Hi all,

      As the first step for being familiar with the technique integrating QML and C++ I went for this example.
      I ran it and I have some questions:

      • Why do we need a Q_PROPERTY macro there? Yeah, I know that it's said that it declares a property that could be accessed from QML. But we have two functions for both reading and writing to the data member. (userName) We could have declared a data member named, say, userName, and haven't declared a a Q_PROPERTY macro seemingly.

      • The program does almost nothing and just gets texts! Emitting the signal won't work either there.

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @tomy said in Integrating QML and C++:

      We could have declared a data member named

      You mean a public member? Well, it is called encapsulation in object oriented languages: you make your data fields private and provide read/write methods where you can control the access (for example refuse changes which should not be possible).

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      tomyT 1 Reply Last reply
      1
      • tomyT tomy

        Hi all,

        As the first step for being familiar with the technique integrating QML and C++ I went for this example.
        I ran it and I have some questions:

        • Why do we need a Q_PROPERTY macro there? Yeah, I know that it's said that it declares a property that could be accessed from QML. But we have two functions for both reading and writing to the data member. (userName) We could have declared a data member named, say, userName, and haven't declared a a Q_PROPERTY macro seemingly.

        • The program does almost nothing and just gets texts! Emitting the signal won't work either there.

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

        @tomy said in Integrating QML and C++:

        I ran it and I have some questions:

        • Why do we need a Q_PROPERTY macro there? Yeah, I know that it's said that it declares a property that could be accessed from QML. But we have two functions for both reading and writing to the data member. (userName) We could have declared a data member named, say, userName, and haven't declared a a Q_PROPERTY macro seemingly.

        • The program does almost nothing and just gets texts! Emitting the signal won't work either there.

        hi tomy

        let's see if I can makes a bit more clear for you, with my (limited) knowledge.

        first of lets change the example q_propery a bit so one does not get confused with the nomenclature

        //original
        Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
        
        //new
        Q_PROPERTY(QString userName READ getUserName WRITE setUserName NOTIFY userNameChanged)
        

        On the QML-Side the property is named userName
        you can do property bindings with it:

        userName : "FixesText"
        
        //or
        userName: otherStringProperty
        

        if a bound property is changed the signal userNameChanged is emitted

        on QML-Side you can attach to that via

        onUserNameChanged: console.log("Username was changed", userName)
        

        on cpp side via QObject:::connect()

        connect(this, myClass::userNameChanged, [=]{qDebug() << "Username was changed" << getUserName();});
        

        the signal is always emitted on both sides, QML and cpp

        assigning a new string to the property on qml side

        userName = "New Username"
        

        actually envokes the cpp function setUserName

        If you envoke setUserName from the cpp class, userNameChanged is emitted, if the string actually is different from before:

        If a QML property is bound to userName, QML will call getUserName to get the new string and update all bound properties.

        emitting userNameChanged() from cpp without actually chaning m_userName will have no visible change in your QML code, but it will update all bound properties.

        chaning m_userName without emitting the signal userNameChanged on cpp side will not update the QML part


        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.

        tomyT 1 Reply Last reply
        6
        • jsulmJ jsulm

          @tomy said in Integrating QML and C++:

          We could have declared a data member named

          You mean a public member? Well, it is called encapsulation in object oriented languages: you make your data fields private and provide read/write methods where you can control the access (for example refuse changes which should not be possible).

          tomyT Offline
          tomyT Offline
          tomy
          wrote on last edited by
          #4

          @jsulm
          No, I exactly meant a private date member, say, next to m_userName.

          mrjjM 1 Reply Last reply
          0
          • tomyT tomy

            @jsulm
            No, I exactly meant a private date member, say, next to m_userName.

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @tomy
            But private members are private and
            cannot be accessed by any one outside the class.
            :)

            1 Reply Last reply
            2
            • J.HilkJ J.Hilk

              @tomy said in Integrating QML and C++:

              I ran it and I have some questions:

              • Why do we need a Q_PROPERTY macro there? Yeah, I know that it's said that it declares a property that could be accessed from QML. But we have two functions for both reading and writing to the data member. (userName) We could have declared a data member named, say, userName, and haven't declared a a Q_PROPERTY macro seemingly.

              • The program does almost nothing and just gets texts! Emitting the signal won't work either there.

              hi tomy

              let's see if I can makes a bit more clear for you, with my (limited) knowledge.

              first of lets change the example q_propery a bit so one does not get confused with the nomenclature

              //original
              Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
              
              //new
              Q_PROPERTY(QString userName READ getUserName WRITE setUserName NOTIFY userNameChanged)
              

              On the QML-Side the property is named userName
              you can do property bindings with it:

              userName : "FixesText"
              
              //or
              userName: otherStringProperty
              

              if a bound property is changed the signal userNameChanged is emitted

              on QML-Side you can attach to that via

              onUserNameChanged: console.log("Username was changed", userName)
              

              on cpp side via QObject:::connect()

              connect(this, myClass::userNameChanged, [=]{qDebug() << "Username was changed" << getUserName();});
              

              the signal is always emitted on both sides, QML and cpp

              assigning a new string to the property on qml side

              userName = "New Username"
              

              actually envokes the cpp function setUserName

              If you envoke setUserName from the cpp class, userNameChanged is emitted, if the string actually is different from before:

              If a QML property is bound to userName, QML will call getUserName to get the new string and update all bound properties.

              emitting userNameChanged() from cpp without actually chaning m_userName will have no visible change in your QML code, but it will update all bound properties.

              chaning m_userName without emitting the signal userNameChanged on cpp side will not update the QML part

              tomyT Offline
              tomyT Offline
              tomy
              wrote on last edited by
              #6

              @J.Hilk

              Hi J.Hilk, thank you very much.

              //original
              Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
              
              //new
              Q_PROPERTY(QString userName READ getUserName WRITE setUserName NOTIFY userNameChanged)
              

              On the QML-Side the property is named userName

              So declaring a Q_PROPERTY is the only way to have a property/variable inside the C++ code and also have access to it from QML side and declaring such a property inside the private or even public area (on the C++ side) doesn't provide us with accessing it from the QML side, yes?

              if a bound property is changed the signal userNameChanged is emitted

              Like here:
              onTextChanged: backend.userName = text
              Yeah?

              on QML-Side you can attach to that via

              onUserNameChanged: console.log("Username was changed", userName)
              

              I used it inside the BackEnd:

              BackEnd {
                      id: backend
                      onUserNameChanged: console.log("Username was changed", userName)
                  }
              

              If a QML property is bound to userName, QML will call getUserName to get the new string and update all bound properties.

              Like here?
              text: backend.userName

              J.HilkJ 1 Reply Last reply
              0
              • tomyT tomy

                @J.Hilk

                Hi J.Hilk, thank you very much.

                //original
                Q_PROPERTY(QString userName READ userName WRITE setUserName NOTIFY userNameChanged)
                
                //new
                Q_PROPERTY(QString userName READ getUserName WRITE setUserName NOTIFY userNameChanged)
                

                On the QML-Side the property is named userName

                So declaring a Q_PROPERTY is the only way to have a property/variable inside the C++ code and also have access to it from QML side and declaring such a property inside the private or even public area (on the C++ side) doesn't provide us with accessing it from the QML side, yes?

                if a bound property is changed the signal userNameChanged is emitted

                Like here:
                onTextChanged: backend.userName = text
                Yeah?

                on QML-Side you can attach to that via

                onUserNameChanged: console.log("Username was changed", userName)
                

                I used it inside the BackEnd:

                BackEnd {
                        id: backend
                        onUserNameChanged: console.log("Username was changed", userName)
                    }
                

                If a QML property is bound to userName, QML will call getUserName to get the new string and update all bound properties.

                Like here?
                text: backend.userName

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

                Hi @tomy

                So declaring a Q_PROPERTY is the only way to have a property/variable inside the C++ code and also have access to it from QML side and declaring such a property inside the private or even public area (on the C++ side) doesn't provide us with accessing it from the QML side, yes?

                Q_Property is a Macro so I would asume it does not matter if its in the public, or private section of your class. But your read &write functions defenitly have to be public.

                It is not the only way, but the most convenient. I know of one more way to get a value from a cpp class:

                //in your header
                public:
                    Q_INVOKABLE int getIntValueFromCpp(){return qrand();}
                
                //In qml
                val intValue = myCppObject.getIntValueFromCpp()
                

                if a bound property is changed the signal userNameChanged is emitted

                Like here:
                onTextChanged: backend.userName = text
                Yeah?

                Yes as soon as text changes the in your backend setUserName is invoked, thanks to the Q_PROPERTY makro, and because of the body of setUserName userNameChanged is emitted if text != userName

                If a QML property is bound to userName, QML will call getUserName to get the new string and update all bound properties.

                Like here?
                text: backend.userName

                yes:
                : = Propertybinding
                = = Asigning a Value

                keep in mind, asigning a value (=) will destroy a previous binding.


                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

                • Login

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