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. Can't reset QFlag in simple class
Forum Updated to NodeBB v4.3 + New Features

Can't reset QFlag in simple class

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 1.7k 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.
  • Please_Help_me_DP Offline
    Please_Help_me_DP Offline
    Please_Help_me_D
    wrote on last edited by
    #1

    Hi,

    I'm trying implement QFlags. I wrote enum in MyClass but in this class I can only set this flag only once. After that I can't see any changes in Debugger in variable MyFlags flag;. Why? Here is the code:

    #include <QFlags>
    
    class MyClass
    {
    public:
        enum MyFlag {
            Yes, // default
            No
        };
        Q_DECLARE_FLAGS(MyFlags, MyFlag)
    
        MyClass(){
            flag.setFlag(Yes); // Yes(0)
            flag.setFlag(No); // No(1)
            flag.setFlag(Yes); // No(1)
            flag.setFlag(No); // No(1)
            flag.setFlag(Yes); // No(1)
        }
    
    private:
        MyFlags flag;
    };
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #7

      Hi
      I think its due to using a value of zero for one of the enums.

      try with

      enum MyFlag {
              Yes = 1, // default
              No =2
          };
      

      then it looks as expected
      alt text

      Please_Help_me_DP 1 Reply Last reply
      2
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Did you actually check the current value after setting it? Otherwise I don't see how you would really know that it does not work.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        Please_Help_me_DP 1 Reply Last reply
        1
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #3

          Hi
          Its store OR combination of the enums. (in your case zero and 1 )
          The code is

           Q_DECL_RELAXED_CONSTEXPR inline QFlags &setFlag(Enum flag, bool on = true) noexcept
              {
                  return on ? (*this |= flag) : (*this &= ~Int(flag));
              }
          
          

          becomes
          value =0
          value |= 0
          value |= 1
          value |= 0
          ...

          So it seems you are expecting it to behave differently?

          1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            Did you actually check the current value after setting it? Otherwise I don't see how you would really know that it does not work.

            Please_Help_me_DP Offline
            Please_Help_me_DP Offline
            Please_Help_me_D
            wrote on last edited by
            #4

            @Christian-Ehrlicher yes, I set a breakpoint and line by line watch the status of variable flag. And in other my application the behavior is the same and I can see this not only with debugger but also how the application runs.

            @mrjj thank you for explanation but this code exceeds my knowledge on C/C++ operators :)
            I wanted that QFlag would be a trigger wich has two positions: Yes and No. I could replace it with bool variable but I want to get experience with QFlags (or C++ flags).
            So inside my class I need to be able to change the satus of flag manually. I thought if I write flag.setFlag(Yes); then flag.testFlag(Yes); should return true and in opposite: flag.setFlag(No); flag.testFlag(No); should return true
            But this doesn't work like I expected...

            mrjjM 1 Reply Last reply
            0
            • Please_Help_me_DP Please_Help_me_D

              @Christian-Ehrlicher yes, I set a breakpoint and line by line watch the status of variable flag. And in other my application the behavior is the same and I can see this not only with debugger but also how the application runs.

              @mrjj thank you for explanation but this code exceeds my knowledge on C/C++ operators :)
              I wanted that QFlag would be a trigger wich has two positions: Yes and No. I could replace it with bool variable but I want to get experience with QFlags (or C++ flags).
              So inside my class I need to be able to change the satus of flag manually. I thought if I write flag.setFlag(Yes); then flag.testFlag(Yes); should return true and in opposite: flag.setFlag(No); flag.testFlag(No); should return true
              But this doesn't work like I expected...

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

              @Please_Help_me_D
              Hi
              yes a bool would act as a toggle but QFlags is
              actually more like a list of bools.
              You can then set one or more of these bools.

              so say you had something to describe a person

               enum MyFlag {
                      Clever, // default
                      Handsome,
                     Rich
                  };
              

              then
              flag.setFlag( Clever );
              flag.setFlag( Handsome );

              Then you set the flags for the person to be Clever and handsome.

              For your exmaple to make it flip/flop you would have to do
              flag.setFlag(Yes ,true ); // turn on
              flag.setFlag(Yes, false); // turn off
              flag.setFlag(No); // turn ON

              Setting No alone , will not turn off Yes.
              It means that No is on also. (or off)

              Hope this makes better sense then :)

              Please_Help_me_DP 1 Reply Last reply
              1
              • mrjjM mrjj

                @Please_Help_me_D
                Hi
                yes a bool would act as a toggle but QFlags is
                actually more like a list of bools.
                You can then set one or more of these bools.

                so say you had something to describe a person

                 enum MyFlag {
                        Clever, // default
                        Handsome,
                       Rich
                    };
                

                then
                flag.setFlag( Clever );
                flag.setFlag( Handsome );

                Then you set the flags for the person to be Clever and handsome.

                For your exmaple to make it flip/flop you would have to do
                flag.setFlag(Yes ,true ); // turn on
                flag.setFlag(Yes, false); // turn off
                flag.setFlag(No); // turn ON

                Setting No alone , will not turn off Yes.
                It means that No is on also. (or off)

                Hope this makes better sense then :)

                Please_Help_me_DP Offline
                Please_Help_me_DP Offline
                Please_Help_me_D
                wrote on last edited by Please_Help_me_D
                #6

                @mrjj thank, now I understood but the problem is in this way they also don't work.
                I just tried to rewrite MyClass here it is:

                #include <QFlags>
                
                class MyClass
                {
                public:
                    enum MyFlag {
                        Yes, // default
                        No
                    };
                    Q_DECLARE_FLAGS(MyFlags, MyFlag)
                
                    MyClass(){
                        flag.setFlag(Yes, true);
                        bool a = flag.testFlag(Yes); // a == true
                
                        flag.setFlag(Yes, false);
                        bool b = flag.testFlag(Yes); // b == true
                
                        flag.setFlag(Yes, true);
                        bool c = flag.testFlag(Yes); // c == true
                    }
                
                private:
                    MyFlags flag;
                };
                

                Why all the three bool vars are true? Is that ok?
                6cc5c7b0-2e62-4e1f-9593-5cd74e6329c1-image.png

                1 Reply Last reply
                0
                • mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #7

                  Hi
                  I think its due to using a value of zero for one of the enums.

                  try with

                  enum MyFlag {
                          Yes = 1, // default
                          No =2
                      };
                  

                  then it looks as expected
                  alt text

                  Please_Help_me_DP 1 Reply Last reply
                  2
                  • mrjjM mrjj

                    Hi
                    I think its due to using a value of zero for one of the enums.

                    try with

                    enum MyFlag {
                            Yes = 1, // default
                            No =2
                        };
                    

                    then it looks as expected
                    alt text

                    Please_Help_me_DP Offline
                    Please_Help_me_DP Offline
                    Please_Help_me_D
                    wrote on last edited by
                    #8

                    @mrjj huh now it works :)
                    thank you!

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      Hi,

                      It is shown in and explained in the QFlags that each item of your flags need to have a different value (1 -> 2 -> 4 -> 8 -> etc.) that can be ORed otherwise you cannot establish which was set. You can do that using a binary format for your number, it will make things clearer.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      Please_Help_me_DP 1 Reply Last reply
                      3
                      • SGaistS SGaist

                        Hi,

                        It is shown in and explained in the QFlags that each item of your flags need to have a different value (1 -> 2 -> 4 -> 8 -> etc.) that can be ORed otherwise you cannot establish which was set. You can do that using a binary format for your number, it will make things clearer.

                        Please_Help_me_DP Offline
                        Please_Help_me_DP Offline
                        Please_Help_me_D
                        wrote on last edited by
                        #10

                        @SGaist thank you!
                        But it is always difficult for me to read documentation about something new that I don't have any idea. It becomes much easier when I already have some representation about studied topic.
                        As example I've read both this and that but nothing helped me to solve my task. I'm like a slowpoke :)
                        But now when I know that QFlag is something like a list of boolean variables I can match documentation with my needs. I always search "how to solve my problem" in Internet and only then I disturb people from communities.
                        This is just my excuses so you would not think that I don't do anything to solve my problem by myself :)

                        I really appreciate forum's people help because you save a lot of time and nerves and honestly saying I would have never learned programming (Matlab and C/C++) if there were not such communities.

                        mrjjM 1 Reply Last reply
                        0
                        • Please_Help_me_DP Please_Help_me_D

                          @SGaist thank you!
                          But it is always difficult for me to read documentation about something new that I don't have any idea. It becomes much easier when I already have some representation about studied topic.
                          As example I've read both this and that but nothing helped me to solve my task. I'm like a slowpoke :)
                          But now when I know that QFlag is something like a list of boolean variables I can match documentation with my needs. I always search "how to solve my problem" in Internet and only then I disturb people from communities.
                          This is just my excuses so you would not think that I don't do anything to solve my problem by myself :)

                          I really appreciate forum's people help because you save a lot of time and nerves and honestly saying I would have never learned programming (Matlab and C/C++) if there were not such communities.

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

                          @Please_Help_me_D

                          Hi
                          Yes its like a list
                          but to make it take up far less space, it uses bits instead of a bool.
                          So basically QFlags helps you get/and set the bits.

                          You know for programming a value can also be shown as binary 0 and 1 ?

                          When you OR something, then just one of the bit has to be set then it becomes set in the result too.

                          0 1 0 1 OR
                          0 1 1 0
                          -------
                          0 1 1 1
                          

                          with AND operator both bits must be set to be set in the result.

                          Thats how QFlags works interinally

                          if we look at

                           Q_DECL_RELAXED_CONSTEXPR inline QFlags &setFlag(Enum flag, bool on = true) noexcept
                              {
                                  return on ? (*this |= flag) : (*this &= ~Int(flag));
                              }
                          
                          

                          then it says

                          if (on is true )
                          value = value OR flag ( in your case yes )
                          else if on is false ( to turn off )
                          value = value AND (negative) flag

                          the last part is taking out the bits that belong to the value for the flag.

                          So AND / OR is not that difficult to understand at a high level as it simply
                          manipulate the values as bits.

                          Please_Help_me_DP 1 Reply Last reply
                          2
                          • mrjjM mrjj

                            @Please_Help_me_D

                            Hi
                            Yes its like a list
                            but to make it take up far less space, it uses bits instead of a bool.
                            So basically QFlags helps you get/and set the bits.

                            You know for programming a value can also be shown as binary 0 and 1 ?

                            When you OR something, then just one of the bit has to be set then it becomes set in the result too.

                            0 1 0 1 OR
                            0 1 1 0
                            -------
                            0 1 1 1
                            

                            with AND operator both bits must be set to be set in the result.

                            Thats how QFlags works interinally

                            if we look at

                             Q_DECL_RELAXED_CONSTEXPR inline QFlags &setFlag(Enum flag, bool on = true) noexcept
                                {
                                    return on ? (*this |= flag) : (*this &= ~Int(flag));
                                }
                            
                            

                            then it says

                            if (on is true )
                            value = value OR flag ( in your case yes )
                            else if on is false ( to turn off )
                            value = value AND (negative) flag

                            the last part is taking out the bits that belong to the value for the flag.

                            So AND / OR is not that difficult to understand at a high level as it simply
                            manipulate the values as bits.

                            Please_Help_me_DP Offline
                            Please_Help_me_DP Offline
                            Please_Help_me_D
                            wrote on last edited by Please_Help_me_D
                            #12

                            @mrjj thank you!
                            I understood something but some interesting things I don't. Here what I get.
                            Yes I understand byte/bit

                            This:

                            on ? (*this |= flag) : (*this &= ~Int(flag));
                            

                            is equal to:

                            if ( on == true ){
                                *this = (*this || flag);
                            } else {
                                *this = (*this &~ Int(flag));
                            }
                            

                            right?
                            If so then to understand the mathematics I need to understand what in bit representation is: *this, flag, Int(flag)
                            In my case flag is equal to 1 right ( enum MyFlag { Yes = 1} )? in bit representation 0001
                            But what is in *this before assigning anything (operator =) and what function Int() does? simply converts flag to integer? as I know this type of casting doesn't change bits of the number it simply tells "these bits should be read as int"
                            Something like that:)

                            ||________________
                            By the way how to turn on notifications when somebody answers me or writes in topic created by me?

                            mrjjM 1 Reply Last reply
                            0
                            • Please_Help_me_DP Please_Help_me_D

                              @mrjj thank you!
                              I understood something but some interesting things I don't. Here what I get.
                              Yes I understand byte/bit

                              This:

                              on ? (*this |= flag) : (*this &= ~Int(flag));
                              

                              is equal to:

                              if ( on == true ){
                                  *this = (*this || flag);
                              } else {
                                  *this = (*this &~ Int(flag));
                              }
                              

                              right?
                              If so then to understand the mathematics I need to understand what in bit representation is: *this, flag, Int(flag)
                              In my case flag is equal to 1 right ( enum MyFlag { Yes = 1} )? in bit representation 0001
                              But what is in *this before assigning anything (operator =) and what function Int() does? simply converts flag to integer? as I know this type of casting doesn't change bits of the number it simply tells "these bits should be read as int"
                              Something like that:)

                              ||________________
                              By the way how to turn on notifications when somebody answers me or writes in topic created by me?

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

                              @Please_Help_me_D

                              Yes odd syntax is called Conditional ternary operator:
                              but is just a one liner if else.

                              (condition) ? (if_true) : (if_false)

                              The *this de reference the this pointer.
                              so its what it points to.
                              This is done to trigger the operator = which QFlags have overloaded.
                              so its a way to assign the value to it self using =

                              the Int() is a type cast like (Int)flag;
                              But its a bit more if we look at source

                              #if defined(Q_CC_MSVC) || defined(Q_CLANG_QDOC)
                                  // see above for MSVC
                                  // the definition below is too complex for qdoc
                                  typedef int Int;
                              #else
                                  typedef typename std::conditional<
                                          std::is_unsigned<typename std::underlying_type<Enum>::type>::value,
                                          unsigned int,
                                          signed int
                                      >::type Int;
                              #endif
                              

                              so when not MSVC compiler it also checks the type

                              And if you think that looks strange, you are right :)

                              Its c++ templates and while really useful, its also
                              often ugly and unreadable. So ignore it until later in your training.

                              Please_Help_me_DP 1 Reply Last reply
                              1
                              • mrjjM mrjj

                                @Please_Help_me_D

                                Yes odd syntax is called Conditional ternary operator:
                                but is just a one liner if else.

                                (condition) ? (if_true) : (if_false)

                                The *this de reference the this pointer.
                                so its what it points to.
                                This is done to trigger the operator = which QFlags have overloaded.
                                so its a way to assign the value to it self using =

                                the Int() is a type cast like (Int)flag;
                                But its a bit more if we look at source

                                #if defined(Q_CC_MSVC) || defined(Q_CLANG_QDOC)
                                    // see above for MSVC
                                    // the definition below is too complex for qdoc
                                    typedef int Int;
                                #else
                                    typedef typename std::conditional<
                                            std::is_unsigned<typename std::underlying_type<Enum>::type>::value,
                                            unsigned int,
                                            signed int
                                        >::type Int;
                                #endif
                                

                                so when not MSVC compiler it also checks the type

                                And if you think that looks strange, you are right :)

                                Its c++ templates and while really useful, its also
                                often ugly and unreadable. So ignore it until later in your training.

                                Please_Help_me_DP Offline
                                Please_Help_me_DP Offline
                                Please_Help_me_D
                                wrote on last edited by Please_Help_me_D
                                #14

                                @mrjj all the things that depend on the compiler features are far outside of my current possibilities :)
                                So I think I begin to understand the magic behind QFlag.
                                returned value is of type bool and bool is not a single bit but rather a byte (maybe few bytes). So any numbers written in Yes except zero in this expression:

                                *this || flag
                                

                                returnes some byte (bytes) where even a single (or more) bits is not zero. A bool which has even a single (or more) non zero bit should return true right?
                                And I believe that behind this dark veil:

                                *this &~ Int(flag)
                                

                                are hidden all zeroed bits :)

                                By the way is it necessary to assign numbers to enum definitions (Yes, No etc) that are equal the power of 2 (1, 2, 4, 8, 16 ...)? as in many examples

                                mrjjM 1 Reply Last reply
                                0
                                • Please_Help_me_DP Please_Help_me_D

                                  @mrjj all the things that depend on the compiler features are far outside of my current possibilities :)
                                  So I think I begin to understand the magic behind QFlag.
                                  returned value is of type bool and bool is not a single bit but rather a byte (maybe few bytes). So any numbers written in Yes except zero in this expression:

                                  *this || flag
                                  

                                  returnes some byte (bytes) where even a single (or more) bits is not zero. A bool which has even a single (or more) non zero bit should return true right?
                                  And I believe that behind this dark veil:

                                  *this &~ Int(flag)
                                  

                                  are hidden all zeroed bits :)

                                  By the way is it necessary to assign numbers to enum definitions (Yes, No etc) that are equal the power of 2 (1, 2, 4, 8, 16 ...)? as in many examples

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

                                  @Please_Help_me_D

                                  Ok that's good :)
                                  maybe you are ready for
                                  https://www.youtube.com/watch?v=TKEaakjKrMc
                                  Bitwise AND / OR

                                  Actually the dark veil:
                                  is using AND and BINARY NOT
                                  to remove the bits for a flag

                                  Yes, you must use power of 2 values as else some of the values will have
                                  overlapping bit representation and things get funny when you combine certain flags.

                                  Please_Help_me_DP 1 Reply Last reply
                                  1
                                  • mrjjM mrjj

                                    @Please_Help_me_D

                                    Ok that's good :)
                                    maybe you are ready for
                                    https://www.youtube.com/watch?v=TKEaakjKrMc
                                    Bitwise AND / OR

                                    Actually the dark veil:
                                    is using AND and BINARY NOT
                                    to remove the bits for a flag

                                    Yes, you must use power of 2 values as else some of the values will have
                                    overlapping bit representation and things get funny when you combine certain flags.

                                    Please_Help_me_DP Offline
                                    Please_Help_me_DP Offline
                                    Please_Help_me_D
                                    wrote on last edited by
                                    #16

                                    @mrjj thank you
                                    Video helped me to remember what XOR. Also now it I understand how to easilly transform binary data representation to decimals :)

                                    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