Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. How to get a boolean value from QSettings correctly?
Forum Updated to NodeBB v4.3 + New Features

How to get a boolean value from QSettings correctly?

Scheduled Pinned Locked Moved Solved Qt for Python
8 Posts 8 Posters 4.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    NonNT
    wrote on last edited by
    #1

    How to get a boolean value from QSettings correctly without helper function?

    Value is 'str' if setting key is defined
    Value is 'bool' if default value is True
    Value is 'NoneType' if default value is False

    def readSettings(self):
        settings = QSettings()
        showTitle = self.valueToBool(settings.value('Settings/showTitle', True))
    
    def valueToBool(self, value):
        if type(value) is str:
            return True if value == 'true' else False
        elif value is None:
            return False
        else:
            return value
    

    Pyside2 5.13.1 on Manjaro

    JonBJ 1 Reply Last reply
    0
    • N NonNT

      How to get a boolean value from QSettings correctly without helper function?

      Value is 'str' if setting key is defined
      Value is 'bool' if default value is True
      Value is 'NoneType' if default value is False

      def readSettings(self):
          settings = QSettings()
          showTitle = self.valueToBool(settings.value('Settings/showTitle', True))
      
      def valueToBool(self, value):
          if type(value) is str:
              return True if value == 'true' else False
          elif value is None:
              return False
          else:
              return value
      

      Pyside2 5.13.1 on Manjaro

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

      @NonNT
      I thought about this for a while! I claim there is not a perfect solution to your case which obeys your rules, is an in-liner (short, and using only Python in-builts), does not raise an exception, does not use regular expressions and does not evaluate the expression more than once. :)

      The best I can come up with which obeys these is:

      str(expr) in ['true', '1']
      

      Obviously this means that only entries of true or 1 are true, everything else (including None, the empty string ('') and e.g. 0 or 2 or 1.0). You could also accept True or TRUE with str(expr).lower() ....

      Having said that, most people would write a function, and that allows us to reference the value parameter more than once. The shortest I would offer is:

      @staticmethod
      def valueToBool(value):
          return value.lower() == 'true' if isinstance(value, str) else bool(value)
      

      This treats, say, 2 or 1.0 as true rather than false, unlike the in-liner. Which behaviour you prefer for such a case is probably a matter of taste!

      A lot of Pythonistas would write the function multi-line to use int(value) inside a try ... except .... Personally I don't like multi-lines where one would suffice and I just don't like raising exceptions in the way they are fond of, but that's up to you. In any case this would be the opposite of what you are asking for.

      1 Reply Last reply
      2
      • N Offline
        N Offline
        NonNT
        wrote on last edited by
        #3

        @JonB
        It looks great. Thanks

        def writeSettings(self):
            showTitle = self.showTitleCheckBox.isChecked()
            settings = QSettings()
            settings.setValue('Settings/showTitle', showTitle)
        
        def readSettings(self):
            settings = QSettings()
            showTitle = self.valueToBool(settings.value('Settings/showTitle', True))
            self.showTitleCheckBox.setChecked(showTitle)
        
        @staticmethod
        def valueToBool(value):
            return value.lower() == 'true' if isinstance(value, str) else bool(value)
        
        Pablo J. RoginaP 1 Reply Last reply
        1
        • N NonNT

          @JonB
          It looks great. Thanks

          def writeSettings(self):
              showTitle = self.showTitleCheckBox.isChecked()
              settings = QSettings()
              settings.setValue('Settings/showTitle', showTitle)
          
          def readSettings(self):
              settings = QSettings()
              showTitle = self.valueToBool(settings.value('Settings/showTitle', True))
              self.showTitleCheckBox.setChecked(showTitle)
          
          @staticmethod
          def valueToBool(value):
              return value.lower() == 'true' if isinstance(value, str) else bool(value)
          
          Pablo J. RoginaP Offline
          Pablo J. RoginaP Offline
          Pablo J. Rogina
          wrote on last edited by
          #4

          @NonNT said in How to get a boolean value from QSettings correctly?:

          It looks great.

          time to mark your post as solved then? Thanks.

          Upvote the answer(s) that helped you solve the issue
          Use "Topic Tools" button to mark your post as Solved
          Add screenshots via postimage.org
          Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • V Offline
            V Offline
            V__V
            wrote on last edited by V__V
            #5

            PyQt provides an extra type argument to fix such a problem:

            r = settings.value("Settings/showTitle", True, type=bool)
            print(r, type(r))
            False <class 'bool'>
            

            Here i use PyQt 5.9.2

            1 Reply Last reply
            1
            • S Offline
              S Offline
              StarChild
              wrote on last edited by
              #6

              settings.setValue('Settings/showTitle', int(False))

              settings.value('Settings/showTitle', True)

              1 Reply Last reply
              0
              • S Offline
                S Offline
                strawbotics
                wrote on last edited by
                #7

                To make sure results are consistent and repeatable clear the settings before setting them.

                settings.clear()
                settings.setValue("Settings/showTitle", False)
                print(settings.value("Settings/showTitle", type=bool)
                

                This solution works on macOS and Windows.

                The other thing to be careful about when working cross platform is always use the same case for keys and never use case to differentiate two keys. Windows init file is case insensitive while macOS is case sensitive.

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  friedemannkleint
                  wrote on last edited by
                  #8

                  PySide also let's you specify a type:

                  https://doc.qt.io/qtforpython-6/PySide6/QtCore/QSettings.html#PySide6.QtCore.PySide6.QtCore.QSettings.value

                  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