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. Correct syntax for setting C++ property in QML
Forum Updated to NodeBB v4.3 + New Features

Correct syntax for setting C++ property in QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
11 Posts 5 Posters 1.4k Views 1 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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #1

    Hi all -

    I've implemented a display with a MouseArea that, when clicked, change the value of a property defined in a C++ class.

    class Opmode : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(ModeEnum mode READ mode WRITE setMode NOTIFY modeChanged);
    public:
        explicit Opmode(QObject *parent = nullptr);
        ModeEnum mode() { return m_opmode; }
        void setMode(const ModeEnum &m);
        ...
    

    In my QML:

        MouseArea {
            anchors.fill: parent
            onClicked: {
                control.checked = true
                opMode.mode = mode <== this works
    //            opMode.setMode(mode) <== this doesn't
        ...
    

    I guess I've never done this before. Is there some reason that I can't use the setMode function in the class? And, is my assignment OK? It seems to work, but I'd like to know for sure.

    Thanks...

    J.HilkJ 1 Reply Last reply
    0
    • B Offline
      B Offline
      bjdm
      wrote on last edited by
      #2

      The QML engine uses the QProperty macro to register the cpp method setMode as the symbol to use when setting the property -- it doesn't expose the method itself. opMode.mode = mode is the correct syntax. More here.

      1 Reply Last reply
      2
      • mzimmersM mzimmers

        Hi all -

        I've implemented a display with a MouseArea that, when clicked, change the value of a property defined in a C++ class.

        class Opmode : public QObject
        {
            Q_OBJECT
            Q_PROPERTY(ModeEnum mode READ mode WRITE setMode NOTIFY modeChanged);
        public:
            explicit Opmode(QObject *parent = nullptr);
            ModeEnum mode() { return m_opmode; }
            void setMode(const ModeEnum &m);
            ...
        

        In my QML:

            MouseArea {
                anchors.fill: parent
                onClicked: {
                    control.checked = true
                    opMode.mode = mode <== this works
        //            opMode.setMode(mode) <== this doesn't
            ...
        

        I guess I've never done this before. Is there some reason that I can't use the setMode function in the class? And, is my assignment OK? It seems to work, but I'd like to know for sure.

        Thanks...

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

        @mzimmers you aren't meant to call the getter and setter of a Q_PROPERTY from the QML side. Your assignment is ok, it's how it's supposed to be.

        For completeness, if you make your setMode a (public)slot or mark it explicitly with the Q_INVOKAVBLE makro, then you can also call the setter from QML


        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.

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

          @mzimmers you aren't meant to call the getter and setter of a Q_PROPERTY from the QML side. Your assignment is ok, it's how it's supposed to be.

          For completeness, if you make your setMode a (public)slot or mark it explicitly with the Q_INVOKAVBLE makro, then you can also call the setter from QML

          mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on last edited by mzimmers
          #4

          @J-Hilk said in Correct syntax for setting C++ property in QML:

          For completeness, if you make your setMode a (public)slot or mark it explicitly with the Q_INVOKAVBLE makro, then you can also call the setter from QML

          Well, setMode is in my Q_INVOKABLE macro. It's not declared as a slot, but I thought there was nothing special about slot functions?

          EDIT:

          I just tried marking setMode() as a slot, and now that line works. Thanks for the help, guys, though I'm not sure I fully understand why it needs to be declared a slot.

          JoeCFDJ 1 Reply Last reply
          0
          • mzimmersM mzimmers

            @J-Hilk said in Correct syntax for setting C++ property in QML:

            For completeness, if you make your setMode a (public)slot or mark it explicitly with the Q_INVOKAVBLE makro, then you can also call the setter from QML

            Well, setMode is in my Q_INVOKABLE macro. It's not declared as a slot, but I thought there was nothing special about slot functions?

            EDIT:

            I just tried marking setMode() as a slot, and now that line works. Thanks for the help, guys, though I'm not sure I fully understand why it needs to be declared a slot.

            JoeCFDJ Offline
            JoeCFDJ Offline
            JoeCFD
            wrote on last edited by JoeCFD
            #5

            @mzimmers True. Here the setter may be used by other C++ classes. In QML, it is not needed in this case. Also do not define it if it is not used.
            I often define variables like the following when the setter is not used.
            Q_PROPERTY( bool android MEMBER m_android CONSTANT )
            Q_PROPERTY( bool charging MEMBER m_charging NOTIFY chargingChanged )

            mzimmersM 1 Reply Last reply
            1
            • JoeCFDJ JoeCFD

              @mzimmers True. Here the setter may be used by other C++ classes. In QML, it is not needed in this case. Also do not define it if it is not used.
              I often define variables like the following when the setter is not used.
              Q_PROPERTY( bool android MEMBER m_android CONSTANT )
              Q_PROPERTY( bool charging MEMBER m_charging NOTIFY chargingChanged )

              mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by
              #6

              From a best practices standpoint, is one of these preferred over the other?

              opMode.mode = mode
              opMode.setMode(mode)
              
              JoeCFDJ GrecKoG 3 Replies Last reply
              0
              • mzimmersM mzimmers

                From a best practices standpoint, is one of these preferred over the other?

                opMode.mode = mode
                opMode.setMode(mode)
                
                JoeCFDJ Offline
                JoeCFDJ Offline
                JoeCFD
                wrote on last edited by JoeCFD
                #7

                @mzimmers If you still remember encapsulation of C++, opMode.setMode(mode) is preferred in C++ classes. But in QML, encapsulation has been sort of dropped. Any call from C++ classes use setter. In QML, you can use opMode.mode = mode. However, if this change or opMode.mode is used in some other QML files and you need to send out modeChanged signal, you will need opMode.setMode(mode).

                1 Reply Last reply
                0
                • mzimmersM mzimmers

                  From a best practices standpoint, is one of these preferred over the other?

                  opMode.mode = mode
                  opMode.setMode(mode)
                  
                  JoeCFDJ Offline
                  JoeCFDJ Offline
                  JoeCFD
                  wrote on last edited by JoeCFD
                  #8

                  @mzimmers My previous answer may not be right completely. You can not call opMode.setMode(mode) because mode is not registered as type? Is it an enum? If yes, define it
                  https://forum.qt.io/topic/109031/passing-enum-into-c-function-like-parameter-from-qml-how/8

                  opMode.mode = mode /* no notification /
                  opMode.setMode(mode) /
                  with notification since emit modeChanged is defined in this function */

                  /* qml supported types */
                  https://doc.qt.io/qt-6/qtqml-cppintegration-data.html

                  1 Reply Last reply
                  0
                  • mzimmersM mzimmers

                    From a best practices standpoint, is one of these preferred over the other?

                    opMode.mode = mode
                    opMode.setMode(mode)
                    
                    GrecKoG Offline
                    GrecKoG Offline
                    GrecKo
                    Qt Champions 2018
                    wrote on last edited by
                    #9

                    @mzimmers said in Correct syntax for setting C++ property in QML:

                    From a best practices standpoint, is one of these preferred over the other?

                    opMode.mode = mode
                    opMode.setMode(mode)
                    

                    opMode.mode = mode is. Prefer to use properties when possible.

                    Contrary to what JoeCFD is saying, this is more encapsulated than calling setMode. You are not acting on the C++ variable anyway, you are going through the QML engine and it can make use of this for stuff like behaviors for example.

                    When doing opMode.mode = mode the modeChanged signal WILL be called (provided that your WRITE method is correctly coded).

                    JoeCFDJ 1 Reply Last reply
                    1
                    • mzimmersM Offline
                      mzimmersM Offline
                      mzimmers
                      wrote on last edited by
                      #10

                      For the sake of completeness in this topic, I think I've covered all my other bases. I've defined the enums appropriately:

                      // opmode.h
                      namespace OpmodeNS {
                          Q_NAMESPACE
                          typedef enum ModeEnum {
                              Standard,
                              Saving,
                              Boost,
                              Service
                          } opmodeEnums;
                          Q_ENUM_NS(ModeEnum)
                      }
                      

                      and registered it accordingly:

                      // main.cpp
                      // register the Opmode enums so they can be used in QML.
                      qmlRegisterUncreatableMetaObject(
                          OpmodeNS::staticMetaObject, // meta object created by Q_NAMESPACE macro
                          "Opmodes",                // import statement (can be any string)
                          1, 0,                           // major and minor version of the import
                          "OpModes",                    // name used in QML (does not have to match C++ name)
                          "Error: only enums"             // error in case someone tries to create an object
                       );
                      

                      And my WRITE method:

                      // opmode.cpp
                      void Opmode::setMode(const ModeEnum &m)
                      {
                          if (m != m_opmode) {
                              m_opmode = m;
                              emit modeChanged(m_opmode);
                          }
                      }
                      

                      Thanks to everyone for the input on this; as usual, it's been educational.

                      1 Reply Last reply
                      1
                      • GrecKoG GrecKo

                        @mzimmers said in Correct syntax for setting C++ property in QML:

                        From a best practices standpoint, is one of these preferred over the other?

                        opMode.mode = mode
                        opMode.setMode(mode)
                        

                        opMode.mode = mode is. Prefer to use properties when possible.

                        Contrary to what JoeCFD is saying, this is more encapsulated than calling setMode. You are not acting on the C++ variable anyway, you are going through the QML engine and it can make use of this for stuff like behaviors for example.

                        When doing opMode.mode = mode the modeChanged signal WILL be called (provided that your WRITE method is correctly coded).

                        JoeCFDJ Offline
                        JoeCFDJ Offline
                        JoeCFD
                        wrote on last edited by JoeCFD
                        #11

                        @GrecKo
                        In C++ the way of mode access in QML like opMode.mode = mode is like public access and is not preferred in C++. That is what I meant.
                        Contrary to what JoeCFD is saying, this is more encapsulated than calling setMode. You are not acting on the C++ variable anyway, you are going through the QML engine and it can make use of this for stuff like behaviors for example.

                        Good to know.
                        When doing opMode.mode = mode the modeChanged signal WILL be called (provided that your WRITE method is correctly coded).

                        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