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. Unable to change bools in C++ struct
Forum Updated to NodeBB v4.3 + New Features

Unable to change bools in C++ struct

Scheduled Pinned Locked Moved Solved QML and Qt Quick
25 Posts 5 Posters 3.3k Views 3 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 mzimmers

    Hi all -

    Just ran across weird behavior -- my attempts to set boolean members of a C++ struct don't work in my app.

    struct Schedule
    {
        Q_GADGET
        QML_VALUE_TYPE(schedule)
        QML_STRUCTURED_VALUE 
    
        Q_PROPERTY(QString name MEMBER m_name)
        Q_PROPERTY(bool maintenance MEMBER m_maintenance)
    public:
        QString m_name = QString();
        bool m_maintenance = false;
        ...
    

    and

    ColumnLayout {
        id: scheduleScreen
        property schedule newSchedule: ({})
    
        Component.onCompleted: {
            newSchedule.maintenance = true
            console.log("ScheduleScreen.qml: newSchedule.maintenance is " + newSchedule.maintenance)
        }
        ...
    

    produces this output:

    qml: ScheduleScreen.qml: newSchedule.maintenance is false
    

    Same behavior with another bool value in my struct, but changing other values (such as name) works.

    I also tried reducing this to a minimal example, but that worked (ugh).

    Any ideas where I went wrong with this? Qt 6.5.3, Windows.

    Thanks...

    JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by
    #6

    @mzimmers said in Unable to change bools in C++ struct:

    I also tried reducing this to a minimal example, but that worked (ugh).

    This really means you need to start from such a good situation, or from a bad situation, and work towards the other. Till you can produce a "this works, and with this tiny change that does not work".

    GrecKoG mzimmersM 2 Replies Last reply
    1
    • JonBJ JonB

      @mzimmers said in Unable to change bools in C++ struct:

      I also tried reducing this to a minimal example, but that worked (ugh).

      This really means you need to start from such a good situation, or from a bad situation, and work towards the other. Till you can produce a "this works, and with this tiny change that does not work".

      GrecKoG Offline
      GrecKoG Offline
      GrecKo
      Qt Champions 2018
      wrote on last edited by
      #7

      @mzimmers
      Do a copy of your schedule before modifying it and assign it back when you are done.

      mzimmersM 1 Reply Last reply
      0
      • GrecKoG GrecKo

        @mzimmers
        Do a copy of your schedule before modifying it and assign it back when you are done.

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

        @GrecKo this:

            Component.onCompleted: {
                var tempSchedule = newSchedule
                console.log("ScheduleScreen.qml: newSchedule is " + newSchedule)
                tempSchedule.name = "xxx"
                tempSchedule.m_maintenance = true
                tempSchedule.timeOffset = 55
                tempSchedule.timeFrame = ScheduleEnums.TIMEFRAME_DAILY;
                newSchedule = tempSchedule
                console.log("ScheduleScreen.qml: tempSchedule is " + tempSchedule)
                console.log("ScheduleScreen.qml: newSchedule is " + newSchedule)
            }
        

        Produces this:

        qml: ScheduleScreen.qml: newSchedule is Schedule({00000000-0000-0000-0000-000000000000}, , {00000000-0000-0000-0000-000000000000}, false, false, , START_ACTION_TURN_ON, END_ACTION_TURN_OFF, START_WHEN_TIME_OF_DAY, END_WHEN_TIME_OF_DAY, 09:00:00.000, 17:00:00.000, TIMEFRAME_WEEKLY, REPEAT_EVERY_WEEK, , , , 0, )
        qml: ScheduleScreen.qml: tempSchedule is Schedule({00000000-0000-0000-0000-000000000000}, xxx, {00000000-0000-0000-0000-000000000000}, false, false, , START_ACTION_TURN_ON, END_ACTION_TURN_OFF, START_WHEN_TIME_OF_DAY, END_WHEN_TIME_OF_DAY, 09:00:00.000, 17:00:00.000, TIMEFRAME_DAILY, REPEAT_EVERY_WEEK, , , , 55, )
        qml: ScheduleScreen.qml: newSchedule is Schedule({00000000-0000-0000-0000-000000000000}, xxx, {00000000-0000-0000-0000-000000000000}, false, false, , START_ACTION_TURN_ON, END_ACTION_TURN_OFF, START_WHEN_TIME_OF_DAY, END_WHEN_TIME_OF_DAY, 09:00:00.000, 17:00:00.000, TIMEFRAME_DAILY, REPEAT_EVERY_WEEK, , , , 55, )
        

        So...no change. Really odd, isn't it?

        GrecKoG 1 Reply Last reply
        0
        • JonBJ JonB

          @mzimmers said in Unable to change bools in C++ struct:

          I also tried reducing this to a minimal example, but that worked (ugh).

          This really means you need to start from such a good situation, or from a bad situation, and work towards the other. Till you can produce a "this works, and with this tiny change that does not work".

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

          @JonB agree completely, though I'm not sure what the next step is, given how "close to the top" this code is. It probably has something to do with how I coded my struct, but I sure can't see what might be doing this.

          fcarneyF 1 Reply Last reply
          0
          • mzimmersM mzimmers

            @JonB agree completely, though I'm not sure what the next step is, given how "close to the top" this code is. It probably has something to do with how I coded my struct, but I sure can't see what might be doing this.

            fcarneyF Offline
            fcarneyF Offline
            fcarney
            wrote on last edited by
            #10

            @mzimmers when I get strange stuff not working I do a clean, run qmake, build. Sometimes it is just a moc issue. Not sure how that works with cmake though.

            C++ is a perfectly valid school of magic.

            mzimmersM 1 Reply Last reply
            1
            • fcarneyF fcarney

              @mzimmers when I get strange stuff not working I do a clean, run qmake, build. Sometimes it is just a moc issue. Not sure how that works with cmake though.

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

              @fcarney tried that -- same results. Good suggestion, though.

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

                OK, so I discovered something, but I don't understand it. I stepped through this in the debugger, and confirmed the problem is in the C++ side:Screenshot 2023-10-18 142850.png

                Then, for lack of anything else to try, I removed the initializer in my struct:

                // bool m_maintenance = false; // before
                bool m_maintenance; // now
                

                and...
                Screenshot 2023-10-18 143100.png
                For another test, I added this line to my c'tor:

                bool m_maintenance = false;
                

                And got the original (bad) result.

                I also "changed polarity" (initialize to true; try to set to false) with the same (bad) result.

                So...this problem just got a little bigger. I'm not willing to release code to the field that creates structs with uninitialized values; I need to figure out what's going on here.

                EDIT: this occurs on 6.6 as well as 6.5.3.

                ANY ideas, no matter how far-fetched, are welcome. Thanks...

                JoeCFDJ 1 Reply Last reply
                0
                • mzimmersM mzimmers

                  OK, so I discovered something, but I don't understand it. I stepped through this in the debugger, and confirmed the problem is in the C++ side:Screenshot 2023-10-18 142850.png

                  Then, for lack of anything else to try, I removed the initializer in my struct:

                  // bool m_maintenance = false; // before
                  bool m_maintenance; // now
                  

                  and...
                  Screenshot 2023-10-18 143100.png
                  For another test, I added this line to my c'tor:

                  bool m_maintenance = false;
                  

                  And got the original (bad) result.

                  I also "changed polarity" (initialize to true; try to set to false) with the same (bad) result.

                  So...this problem just got a little bigger. I'm not willing to release code to the field that creates structs with uninitialized values; I need to figure out what's going on here.

                  EDIT: this occurs on 6.6 as well as 6.5.3.

                  ANY ideas, no matter how far-fetched, are welcome. Thanks...

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

                  Check this out.
                  https://stackoverflow.com/questions/1069621/are-members-of-a-c-struct-initialized-to-0-by-default
                  It may not be a C++ problem. Instead it is a C problem. Struct is very C style. I even avoid using it.

                  mzimmersM 1 Reply Last reply
                  0
                  • JoeCFDJ JoeCFD

                    Check this out.
                    https://stackoverflow.com/questions/1069621/are-members-of-a-c-struct-initialized-to-0-by-default
                    It may not be a C++ problem. Instead it is a C problem. Struct is very C style. I even avoid using it.

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

                    @JoeCFD interesting article, though my issue is with modification, not initialization.

                    Regarding the use of structs: I suppose I could use a class, but I'd be astonished if that made a difference. I'm deliberately avoiding using QObject here, too.

                    JoeCFDJ 1 Reply Last reply
                    0
                    • mzimmersM mzimmers

                      @JoeCFD interesting article, though my issue is with modification, not initialization.

                      Regarding the use of structs: I suppose I could use a class, but I'd be astonished if that made a difference. I'm deliberately avoiding using QObject here, too.

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

                      @mzimmers bool m_maintenance; // now
                      is undefined.

                      can you try:
                      bool m_maintenance{ false };
                      I do not know if it will make a difference.

                      mzimmersM 2 Replies Last reply
                      1
                      • JoeCFDJ JoeCFD

                        @mzimmers bool m_maintenance; // now
                        is undefined.

                        can you try:
                        bool m_maintenance{ false };
                        I do not know if it will make a difference.

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

                        @JoeCFD said in Unable to change bools in C++ struct:

                        @mzimmers bool m_maintenance; // now
                        is undefined.

                        I realize that, and that's not acceptable. But currently I have the options of leaving it undefined, or initializing it and (somehow) making it QML-immutable in the process.

                        I can't even modify it if I initialize it in QML, like this:

                            property schedule newSchedule: ({ "maintenance": false })
                        
                        1 Reply Last reply
                        0
                        • JoeCFDJ JoeCFD

                          @mzimmers bool m_maintenance; // now
                          is undefined.

                          can you try:
                          bool m_maintenance{ false };
                          I do not know if it will make a difference.

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

                          @JoeCFD said in Unable to change bools in C++ struct:

                          can you try:
                          bool m_maintenance{ false };

                          Same (bad) result. Thanks for the suggestion, though.

                          JoeCFDJ 1 Reply Last reply
                          0
                          • mzimmersM mzimmers

                            @JoeCFD said in Unable to change bools in C++ struct:

                            can you try:
                            bool m_maintenance{ false };

                            Same (bad) result. Thanks for the suggestion, though.

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

                            @mzimmers
                            try
                            class Schedule

                            not struct Schedule
                            .

                            mzimmersM GrecKoG 2 Replies Last reply
                            0
                            • JoeCFDJ JoeCFD

                              @mzimmers
                              try
                              class Schedule

                              not struct Schedule
                              .

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

                              @JoeCFD no change in behavior.

                              1 Reply Last reply
                              0
                              • JoeCFDJ JoeCFD

                                @mzimmers
                                try
                                class Schedule

                                not struct Schedule
                                .

                                GrecKoG Offline
                                GrecKoG Offline
                                GrecKo
                                Qt Champions 2018
                                wrote on last edited by
                                #20

                                @JoeCFD struct is just a class where everything is public by default.

                                1 Reply Last reply
                                1
                                • mzimmersM mzimmers

                                  @GrecKo this:

                                      Component.onCompleted: {
                                          var tempSchedule = newSchedule
                                          console.log("ScheduleScreen.qml: newSchedule is " + newSchedule)
                                          tempSchedule.name = "xxx"
                                          tempSchedule.m_maintenance = true
                                          tempSchedule.timeOffset = 55
                                          tempSchedule.timeFrame = ScheduleEnums.TIMEFRAME_DAILY;
                                          newSchedule = tempSchedule
                                          console.log("ScheduleScreen.qml: tempSchedule is " + tempSchedule)
                                          console.log("ScheduleScreen.qml: newSchedule is " + newSchedule)
                                      }
                                  

                                  Produces this:

                                  qml: ScheduleScreen.qml: newSchedule is Schedule({00000000-0000-0000-0000-000000000000}, , {00000000-0000-0000-0000-000000000000}, false, false, , START_ACTION_TURN_ON, END_ACTION_TURN_OFF, START_WHEN_TIME_OF_DAY, END_WHEN_TIME_OF_DAY, 09:00:00.000, 17:00:00.000, TIMEFRAME_WEEKLY, REPEAT_EVERY_WEEK, , , , 0, )
                                  qml: ScheduleScreen.qml: tempSchedule is Schedule({00000000-0000-0000-0000-000000000000}, xxx, {00000000-0000-0000-0000-000000000000}, false, false, , START_ACTION_TURN_ON, END_ACTION_TURN_OFF, START_WHEN_TIME_OF_DAY, END_WHEN_TIME_OF_DAY, 09:00:00.000, 17:00:00.000, TIMEFRAME_DAILY, REPEAT_EVERY_WEEK, , , , 55, )
                                  qml: ScheduleScreen.qml: newSchedule is Schedule({00000000-0000-0000-0000-000000000000}, xxx, {00000000-0000-0000-0000-000000000000}, false, false, , START_ACTION_TURN_ON, END_ACTION_TURN_OFF, START_WHEN_TIME_OF_DAY, END_WHEN_TIME_OF_DAY, 09:00:00.000, 17:00:00.000, TIMEFRAME_DAILY, REPEAT_EVERY_WEEK, , , , 55, )
                                  

                                  So...no change. Really odd, isn't it?

                                  GrecKoG Offline
                                  GrecKoG Offline
                                  GrecKo
                                  Qt Champions 2018
                                  wrote on last edited by
                                  #21

                                  @mzimmers what's the issue on this output? We don't know which field is which. Also why are you using m_maintenance in QML? That's not the name of your property.

                                  mzimmersM 1 Reply Last reply
                                  0
                                  • GrecKoG GrecKo

                                    @mzimmers what's the issue on this output? We don't know which field is which. Also why are you using m_maintenance in QML? That's not the name of your property.

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

                                    @GrecKo I don't know how that got in there, but that wasn't how it was originally, and it's not how it is now. My screenshots above are correct.

                                    1 Reply Last reply
                                    0
                                    • mzimmersM Offline
                                      mzimmersM Offline
                                      mzimmers
                                      wrote on last edited by
                                      #23

                                      OK, guys - here's a minimal repeatable example:

                                      // schedule.h
                                      #pragma once
                                      
                                      #include <QObject>
                                      #include <QMetaType>
                                      #include <QtQml/qqmlregistration.h>
                                      #include <QtQmlIntegration/QtQmlIntegration>
                                      
                                      struct Schedule
                                      {
                                          Q_GADGET
                                          QML_VALUE_TYPE(schedule)
                                          QML_STRUCTURED_VALUE
                                          Q_PROPERTY(bool maintenance MEMBER m_maintenance)
                                      public:
                                          bool m_maintenance;
                                          Q_INVOKABLE Schedule() {}
                                          bool operator ==(const Schedule &rhs) const {return true;}
                                      };
                                      
                                      // Main.qml
                                      import QtQuick
                                      import QtQuick.Controls
                                      import QtQuick.Layouts
                                      import QtQuick.Window
                                      
                                      Window {
                                          id: mainWindow
                                          width: 640
                                          height: 480
                                          visible: true
                                      
                                          property schedule newSchedule: ({  })
                                      
                                          Switch {
                                              onClicked: {
                                                  console.log("switch is " + checked)
                                                  newSchedule.maintenance = checked
                                                  console.log("newSchedule.maintenance is " + newSchedule.maintenance)
                                              }
                                          }
                                      }
                                      

                                      Output:

                                      qml: switch is true
                                      qml: newSchedule.maintenance is false
                                      qml: switch is false
                                      qml: newSchedule.maintenance is false
                                      qml: switch is true
                                      qml: newSchedule.maintenance is false
                                      qml: switch is false
                                      qml: newSchedule.maintenance is false
                                      

                                      I can provide the cmake file as well if desired, but it doesn't contain anything unusual.

                                      GrecKoG 1 Reply Last reply
                                      0
                                      • mzimmersM mzimmers

                                        OK, guys - here's a minimal repeatable example:

                                        // schedule.h
                                        #pragma once
                                        
                                        #include <QObject>
                                        #include <QMetaType>
                                        #include <QtQml/qqmlregistration.h>
                                        #include <QtQmlIntegration/QtQmlIntegration>
                                        
                                        struct Schedule
                                        {
                                            Q_GADGET
                                            QML_VALUE_TYPE(schedule)
                                            QML_STRUCTURED_VALUE
                                            Q_PROPERTY(bool maintenance MEMBER m_maintenance)
                                        public:
                                            bool m_maintenance;
                                            Q_INVOKABLE Schedule() {}
                                            bool operator ==(const Schedule &rhs) const {return true;}
                                        };
                                        
                                        // Main.qml
                                        import QtQuick
                                        import QtQuick.Controls
                                        import QtQuick.Layouts
                                        import QtQuick.Window
                                        
                                        Window {
                                            id: mainWindow
                                            width: 640
                                            height: 480
                                            visible: true
                                        
                                            property schedule newSchedule: ({  })
                                        
                                            Switch {
                                                onClicked: {
                                                    console.log("switch is " + checked)
                                                    newSchedule.maintenance = checked
                                                    console.log("newSchedule.maintenance is " + newSchedule.maintenance)
                                                }
                                            }
                                        }
                                        

                                        Output:

                                        qml: switch is true
                                        qml: newSchedule.maintenance is false
                                        qml: switch is false
                                        qml: newSchedule.maintenance is false
                                        qml: switch is true
                                        qml: newSchedule.maintenance is false
                                        qml: switch is false
                                        qml: newSchedule.maintenance is false
                                        

                                        I can provide the cmake file as well if desired, but it doesn't contain anything unusual.

                                        GrecKoG Offline
                                        GrecKoG Offline
                                        GrecKo
                                        Qt Champions 2018
                                        wrote on last edited by GrecKo
                                        #24

                                        @mzimmers said in Unable to change bools in C++ struct:

                                        bool operator ==(const Schedule &rhs) const {return true;}

                                        If you remove this non-sensical operator== your code works as expected.

                                        My guess is that the engine modifies a temp Schedule internally, checks the equality and assign it only if it's different. As it's always equal it won't modify it.

                                        mzimmersM 1 Reply Last reply
                                        4
                                        • GrecKoG GrecKo

                                          @mzimmers said in Unable to change bools in C++ struct:

                                          bool operator ==(const Schedule &rhs) const {return true;}

                                          If you remove this non-sensical operator== your code works as expected.

                                          My guess is that the engine modifies a temp Schedule internally, checks the equality and assign it only if it's different. As it's always equal it won't modify it.

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

                                          @GrecKo bingo!

                                          I'd just stubbed out that comparison function to satisfy the compiler, but you were absolutely right. In my app, I'd neglected to include the maintenance member in my comparison function. Seems to work fine now.

                                          Kind of has me wondering -- if I set my compiler options to no optimization, I wonder if it would have worked...

                                          Anyway, thanks to EVERYONE for the help on this.

                                          1 Reply Last reply
                                          0
                                          • mzimmersM mzimmers has marked this topic as solved on

                                          • Login

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