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. Wrong enum value from QSettings using Qt 6
Forum Updated to NodeBB v4.3 + New Features

Wrong enum value from QSettings using Qt 6

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 6 Posters 3.6k 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.
  • C Cobra91151
    1 Feb 2023, 12:08

    Hello!

    I have found an issue with my program using Qt 6. For example, I created this method to read the QSettings ini file.

    #define APP_SETTINGS_PATH QDir::toNativeSeparators(QString("%1/settings/%2.ini").arg(QApplication::applicationDirPath(), QString(APP_NAME).remove(QRegularExpression("\\s"))))
    
    QVariant ManageProgram::loadSettings(QString group, QString property, QVariant defaultValue)
    {
        QSettings appSettings(APP_SETTINGS_PATH, QSettings::IniFormat);
        appSettings.beginGroup(group);
        QVariant valueVariant = appSettings.value(property, defaultValue);
        appSettings.endGroup();
        return valueVariant;
    }
    

    Then, I want to get the value from my enum: Connection::State

    Connection::State wlanConnectionState = ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown).value<Connection::State>();
    

    INI file:

    [AppSettings]
    WlanState=2
    

    The stored value is: 2 but it returns as 0 on Qt 6.3.2, Qt 6.4.1, Qt 6.4.2, which breaks some of the features in my program. On Qt 5 this works well and returns the correct enum value: 2. Any ideas? Thank you.

    J Offline
    J Offline
    JonB
    wrote on 1 Feb 2023, 12:14 last edited by
    #3

    @Cobra91151 said in Wrong enum value from QSettings using Qt 6:

    Connection::State

    Where is this enum in the docs, please? I can find enum QAbstractSocket::SocketState?

    Try reading your saved value as an int, do you get the right value? Try converting that to your desired enum, does that work?

    C 1 Reply Last reply 1 Feb 2023, 12:25
    0
    • C Christian Ehrlicher
      1 Feb 2023, 12:13

      Please print a debug output of your QVariant to see if it's a QVariant conversion problem or QSettings.

      qDebug() << ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown);

      C Offline
      C Offline
      Cobra91151
      wrote on 1 Feb 2023, 12:20 last edited by
      #4

      @Christian-Ehrlicher

      Ok. I have recompiled the program:

      qDebug() << ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown);
      It returns: QVariant(QString, "2")

      So, it seems it's QVariant conversion issue.

      1 Reply Last reply
      0
      • C Cobra91151
        1 Feb 2023, 12:08

        Hello!

        I have found an issue with my program using Qt 6. For example, I created this method to read the QSettings ini file.

        #define APP_SETTINGS_PATH QDir::toNativeSeparators(QString("%1/settings/%2.ini").arg(QApplication::applicationDirPath(), QString(APP_NAME).remove(QRegularExpression("\\s"))))
        
        QVariant ManageProgram::loadSettings(QString group, QString property, QVariant defaultValue)
        {
            QSettings appSettings(APP_SETTINGS_PATH, QSettings::IniFormat);
            appSettings.beginGroup(group);
            QVariant valueVariant = appSettings.value(property, defaultValue);
            appSettings.endGroup();
            return valueVariant;
        }
        

        Then, I want to get the value from my enum: Connection::State

        Connection::State wlanConnectionState = ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown).value<Connection::State>();
        

        INI file:

        [AppSettings]
        WlanState=2
        

        The stored value is: 2 but it returns as 0 on Qt 6.3.2, Qt 6.4.1, Qt 6.4.2, which breaks some of the features in my program. On Qt 5 this works well and returns the correct enum value: 2. Any ideas? Thank you.

        J Offline
        J Offline
        J.Hilk
        Moderators
        wrote on 1 Feb 2023, 12:20 last edited by
        #5

        @Cobra91151 are you sure the Enum is correctly registered with the meta system ?

        I think Variant falls back on that.

        Besides that, simply read it as int:

        value<int>()
        

        and cast the result to the enum.


        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
        • J JonB
          1 Feb 2023, 12:14

          @Cobra91151 said in Wrong enum value from QSettings using Qt 6:

          Connection::State

          Where is this enum in the docs, please? I can find enum QAbstractSocket::SocketState?

          Try reading your saved value as an int, do you get the right value? Try converting that to your desired enum, does that work?

          C Offline
          C Offline
          Cobra91151
          wrote on 1 Feb 2023, 12:25 last edited by
          #6

          @JonB

          No, it's my custom enum.

          namespace Connection {
              enum State {
                  NotConnected = 0,
                  Connecting = 1,
                  Connected = 2,
                  Canceled = 3,
                  Unknown = 4
              };
          }
          

          Yes, it works only when converting using toInt() method.

          int wlanState = ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown).toInt();
          wlanConnectionState = static_cast<Connection::State>(wlanState);
          qDebug() << "wlanConnectionState: " << wlanConnectionState;
          

          wlanConnectionState: 2

          Why it fails to convert to enum: wlanConnectionState = ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown).value<Connection::State>();? That's the question.

          C 1 Reply Last reply 1 Feb 2023, 12:25
          0
          • C Cobra91151
            1 Feb 2023, 12:25

            @JonB

            No, it's my custom enum.

            namespace Connection {
                enum State {
                    NotConnected = 0,
                    Connecting = 1,
                    Connected = 2,
                    Canceled = 3,
                    Unknown = 4
                };
            }
            

            Yes, it works only when converting using toInt() method.

            int wlanState = ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown).toInt();
            wlanConnectionState = static_cast<Connection::State>(wlanState);
            qDebug() << "wlanConnectionState: " << wlanConnectionState;
            

            wlanConnectionState: 2

            Why it fails to convert to enum: wlanConnectionState = ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown).value<Connection::State>();? That's the question.

            C Offline
            C Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 1 Feb 2023, 12:25 last edited by
            #7

            @Cobra91151 said in Wrong enum value from QSettings using Qt 6:

            Why it fails to convert to enum

            @J-Hilk

            are you sure the Enum is correctly registered with the meta system ?

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

            C 1 Reply Last reply 1 Feb 2023, 12:28
            1
            • C Christian Ehrlicher
              1 Feb 2023, 12:25

              @Cobra91151 said in Wrong enum value from QSettings using Qt 6:

              Why it fails to convert to enum

              @J-Hilk

              are you sure the Enum is correctly registered with the meta system ?

              C Offline
              C Offline
              Cobra91151
              wrote on 1 Feb 2023, 12:28 last edited by
              #8

              @J-Hilk
              @Christian-Ehrlicher
              @JonB

              I think, it is already registered: Q_DECLARE_METATYPE(Connection::State).
              Or Qt 6 uses different method of registering types?

              J 1 Reply Last reply 1 Feb 2023, 12:32
              0
              • C Cobra91151
                1 Feb 2023, 12:28

                @J-Hilk
                @Christian-Ehrlicher
                @JonB

                I think, it is already registered: Q_DECLARE_METATYPE(Connection::State).
                Or Qt 6 uses different method of registering types?

                J Offline
                J Offline
                J.Hilk
                Moderators
                wrote on 1 Feb 2023, 12:32 last edited by
                #9

                @Cobra91151 did you also use Q_ENUM_NS or Q_ENUM if your declaration is inside a QObject class?


                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
                0
                • C Offline
                  C Offline
                  Cobra91151
                  wrote on 1 Feb 2023, 12:39 last edited by
                  #10

                  @J-Hilk

                  This enum declaration is in constants.h (header file). I use it as a helper file to create some enums/structs/defines there and use it in my program. There is no class in this file.
                  So, it's outside of a QObject class.

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    Cobra91151
                    wrote on 1 Feb 2023, 12:41 last edited by Cobra91151 2 Jan 2023, 12:42
                    #11

                    I think that I need to use something like this in my program.

                    #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
                        int wlanState = ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown).toInt();
                        wlanConnectionState = static_cast<Connection::State>(wlanState);
                    #else
                        wlanConnectionState = ManageProgram::loadSettings("AppSettings", "WlanState", Connection::State::Unknown).value<Connection::State>();
                    #endif
                    

                    The output for both cases: wlanConnectionState: 2

                    I should use the .value<Connection::State>(); in Qt 5 as always. And use .toInt() and then cast the result to the enum in Qt 6 until QVariant conversion problem is fixed.

                    1 Reply Last reply
                    0
                    • C Offline
                      C Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on 1 Feb 2023, 12:43 last edited by
                      #12

                      Works fine for me with Qt6.head + MSVC

                      namespace Connection {
                          enum State {
                              NotConnected = 0,
                              Connecting = 1,
                              Connected = 2,
                              Canceled = 3,
                              Unknown = 4
                          };
                      }
                      Q_DECLARE_METATYPE(Connection::State);  // not even needed for the testcase
                      
                      int main(int argc, char* argv[])
                      {
                          QCoreApplication app(argc, argv);
                          QVariant v(2);
                          Connection::State s = v.value<Connection::State>();
                          if (s == Connection::Connected) 
                              qDebug() << "Connected";
                          else 
                              qDebug() << "Not connected";
                      }
                      

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

                      C 2 Replies Last reply 1 Feb 2023, 12:51
                      1
                      • C Christian Ehrlicher
                        1 Feb 2023, 12:43

                        Works fine for me with Qt6.head + MSVC

                        namespace Connection {
                            enum State {
                                NotConnected = 0,
                                Connecting = 1,
                                Connected = 2,
                                Canceled = 3,
                                Unknown = 4
                            };
                        }
                        Q_DECLARE_METATYPE(Connection::State);  // not even needed for the testcase
                        
                        int main(int argc, char* argv[])
                        {
                            QCoreApplication app(argc, argv);
                            QVariant v(2);
                            Connection::State s = v.value<Connection::State>();
                            if (s == Connection::Connected) 
                                qDebug() << "Connected";
                            else 
                                qDebug() << "Not connected";
                        }
                        
                        C Offline
                        C Offline
                        Cobra91151
                        wrote on 1 Feb 2023, 12:51 last edited by Cobra91151 2 Jan 2023, 12:52
                        #13

                        @Christian-Ehrlicher

                        Yes, it works. So, the enum must be overwritten somewhere in my program which changes the value to 0.
                        I will check it and fix it. Thank you very much for checking it.

                        1 Reply Last reply
                        1
                        • C Christian Ehrlicher
                          1 Feb 2023, 12:43

                          Works fine for me with Qt6.head + MSVC

                          namespace Connection {
                              enum State {
                                  NotConnected = 0,
                                  Connecting = 1,
                                  Connected = 2,
                                  Canceled = 3,
                                  Unknown = 4
                              };
                          }
                          Q_DECLARE_METATYPE(Connection::State);  // not even needed for the testcase
                          
                          int main(int argc, char* argv[])
                          {
                              QCoreApplication app(argc, argv);
                              QVariant v(2);
                              Connection::State s = v.value<Connection::State>();
                              if (s == Connection::Connected) 
                                  qDebug() << "Connected";
                              else 
                                  qDebug() << "Not connected";
                          }
                          
                          C Offline
                          C Offline
                          Cobra91151
                          wrote on 1 Feb 2023, 13:47 last edited by Cobra91151 2 Jan 2023, 21:31
                          #14

                          @Christian-Ehrlicher
                          @JonB
                          @J-Hilk

                          I have commented all wlanConnectionState code in my program where it could be overwritten, recompiled it (clean/run qmake/build) but it still returns as 0. So, I have used @Christian-Ehrlicher example and added my code there.

                          #include <QCoreApplication>
                          #include <QVariant>
                          #include <QSettings>
                          #include <QDir>
                          #include <QRegularExpression>
                          
                          #define APP_NAME "ConsoleApp"
                          #define APP_SETTINGS_PATH QDir::toNativeSeparators(QString("%1/settings/%2.ini").arg(QCoreApplication::applicationDirPath(), QString(APP_NAME).remove(QRegularExpression("\\s"))))
                          
                          namespace Connection {
                              enum State {
                                  NotConnected = 0,
                                  Connecting = 1,
                                  Connected = 2,
                                  Canceled = 3,
                                  Unknown = 4
                              };
                          }
                          
                          Q_DECLARE_METATYPE(Connection::State);  // not even needed for the testcase
                          QVariant loadSettings(QString group, QString property, QVariant defaultValue);
                          
                          int main(int argc, char* argv[])
                          {
                              QCoreApplication app(argc, argv);
                              //QVariant v(2);
                              Connection::State s = loadSettings("AppSettings", "WlanState", Connection::State::Unknown).value<Connection::State>();
                          
                              //int wlanState = loadSettings("AppSettings", "WlanState", Connection::State::Unknown).toInt();
                              //Connection::State s = static_cast<Connection::State>(wlanState);
                          
                              if (s == Connection::Connected) {
                                  qDebug() << "Connected";
                              } else {
                                  qDebug() << "Not connected";
                              }
                          
                              qDebug() << "s: " << s;
                          }
                          
                          QVariant loadSettings(QString group, QString property, QVariant defaultValue)
                          {
                              QSettings appSettings(APP_SETTINGS_PATH, QSettings::IniFormat);
                              appSettings.beginGroup(group);
                              QVariant valueVariant = appSettings.value(property, defaultValue);
                              appSettings.endGroup();
                              return valueVariant;
                          }
                          

                          It also returns:

                          Not connected
                          s:  0
                          

                          When I use this code:

                          int wlanState = loadSettings("AppSettings", "WlanState", Connection::State::Unknown).toInt();
                          Connection::State s = static_cast<Connection::State>(wlanState);
                          

                          The output is the following:

                          Connected
                          s:  2
                          

                          So, it seems that issue with QVariant conversion still exists.
                          Can you confirm (reproduce) it using updated code? Also, you will need the settings directory with .ini file: https://mega.nz/file/EVRwWI5b#4MXbcgqE1aCm_YKEk0leZnMnEGMWw1yuLHL61UlIi54

                          Or create one called ConsoleApp.ini with the following content:

                          [AppSettings]
                          WlanState=2
                          

                          Thank you.

                          1 Reply Last reply
                          0
                          • JoeCFDJ Offline
                            JoeCFDJ Offline
                            JoeCFD
                            wrote on 1 Feb 2023, 23:18 last edited by
                            #15

                            @Cobra91151 said in Wrong enum value from QSettings using Qt 6:

                            namespace Connection {
                            enum State {
                            NotConnected = 0,
                            Connecting = 1,
                            Connected = 2,
                            Canceled = 3,
                            Unknown = 4
                            };
                            }

                            why not use enum class?

                            namespace Connection {
                                enum class State {
                                    NotConnected = 0,
                                    Connecting = 1,
                                    Connected = 2,
                                    Canceled = 3,
                                    Unknown = 4
                                };
                            }
                            
                            C 1 Reply Last reply 2 Feb 2023, 01:17
                            0
                            • JoeCFDJ JoeCFD
                              1 Feb 2023, 23:18

                              @Cobra91151 said in Wrong enum value from QSettings using Qt 6:

                              namespace Connection {
                              enum State {
                              NotConnected = 0,
                              Connecting = 1,
                              Connected = 2,
                              Canceled = 3,
                              Unknown = 4
                              };
                              }

                              why not use enum class?

                              namespace Connection {
                                  enum class State {
                                      NotConnected = 0,
                                      Connecting = 1,
                                      Connected = 2,
                                      Canceled = 3,
                                      Unknown = 4
                                  };
                              }
                              
                              C Offline
                              C Offline
                              Cobra91151
                              wrote on 2 Feb 2023, 01:17 last edited by
                              #16

                              @JoeCFD

                              Hello!

                              I do not think it will work in my case, since I need to store enum value as integer in the .ini file and get it later as enum. On Qt 5 it works as expected. So, I think there is an issue with enum convertion in Qt 6. You can try out my example above to see what the issue is.
                              Anyway, thank you for your reply :)

                              1 Reply Last reply
                              0
                              • C Offline
                                C Offline
                                Christian Ehrlicher
                                Lifetime Qt Champion
                                wrote on 2 Feb 2023, 17:05 last edited by Christian Ehrlicher 2 Feb 2023, 17:50
                                #17

                                Ok, looks like an enum now need Q_ENUM() (even though I think it may be a subtle bug):

                                struct Connection {
                                    Q_GADGET
                                public:
                                        enum State {
                                        NotConnected = 0,
                                        Connecting = 1,
                                        Connected = 2,
                                        Canceled = 3,
                                        Unknown = 4
                                    };
                                    Q_ENUM(State)
                                };
                                

                                This also allows this in your ini file:

                                [AppSettings]
                                WlanState=Connected
                                

                                Will investigate it later on

                                // see https://bugreports.qt.io/browse/QTBUG-109744

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

                                J 1 Reply Last reply 3 Feb 2023, 07:27
                                3
                                • H Offline
                                  H Offline
                                  henrycavill23
                                  Banned
                                  wrote on 3 Feb 2023, 07:21 last edited by
                                  #18
                                  This post is deleted!
                                  1 Reply Last reply
                                  0
                                  • C Christian Ehrlicher
                                    2 Feb 2023, 17:05

                                    Ok, looks like an enum now need Q_ENUM() (even though I think it may be a subtle bug):

                                    struct Connection {
                                        Q_GADGET
                                    public:
                                            enum State {
                                            NotConnected = 0,
                                            Connecting = 1,
                                            Connected = 2,
                                            Canceled = 3,
                                            Unknown = 4
                                        };
                                        Q_ENUM(State)
                                    };
                                    

                                    This also allows this in your ini file:

                                    [AppSettings]
                                    WlanState=Connected
                                    

                                    Will investigate it later on

                                    // see https://bugreports.qt.io/browse/QTBUG-109744

                                    J Offline
                                    J Offline
                                    J.Hilk
                                    Moderators
                                    wrote on 3 Feb 2023, 07:27 last edited by
                                    #19

                                    @Christian-Ehrlicher

                                    @J-Hilk said in Wrong enum value from QSettings using Qt 6:

                                    @Cobra91151 did you also use Q_ENUM_NS or Q_ENUM if your declaration is inside a QObject class?

                                    cough 🤓

                                    might be in it since the beginning of Qt6 ? because I don't remember it ever working without the Q_ENUM macro?


                                    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.

                                    C C 2 Replies Last reply 11 Feb 2023, 11:35
                                    0
                                    • J J.Hilk
                                      3 Feb 2023, 07:27

                                      @Christian-Ehrlicher

                                      @J-Hilk said in Wrong enum value from QSettings using Qt 6:

                                      @Cobra91151 did you also use Q_ENUM_NS or Q_ENUM if your declaration is inside a QObject class?

                                      cough 🤓

                                      might be in it since the beginning of Qt6 ? because I don't remember it ever working without the Q_ENUM macro?

                                      C Offline
                                      C Offline
                                      Cobra91151
                                      wrote on 11 Feb 2023, 11:35 last edited by
                                      #20

                                      @Christian-Ehrlicher @J-Hilk

                                      I see this bug is fixed in Qt 6.5.0 & Qt 6.6.0. The issue is resolved.
                                      Thank you.

                                      1 Reply Last reply
                                      1
                                      • C Cobra91151 has marked this topic as solved on 11 Feb 2023, 11:36
                                      • J J.Hilk
                                        3 Feb 2023, 07:27

                                        @Christian-Ehrlicher

                                        @J-Hilk said in Wrong enum value from QSettings using Qt 6:

                                        @Cobra91151 did you also use Q_ENUM_NS or Q_ENUM if your declaration is inside a QObject class?

                                        cough 🤓

                                        might be in it since the beginning of Qt6 ? because I don't remember it ever working without the Q_ENUM macro?

                                        C Offline
                                        C Offline
                                        Christian Ehrlicher
                                        Lifetime Qt Champion
                                        wrote on 11 Feb 2023, 11:47 last edited by
                                        #21

                                        @J-Hilk said in Wrong enum value from QSettings using Qt 6:

                                        because I don't remember it ever working without the Q_ENUM macro?

                                        It worked in Qt5 so it's a Qt6 regression. And it is very surprising because QVariant<int>() properly converts to an enum whereas QVariant<QString>() did not.

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

                                        1 Reply Last reply
                                        0
                                        • J JonB referenced this topic on 12 Feb 2023, 08:18

                                        • Login

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