[PyQt] A possible bug in PyQt when loading Boolean values via QSettings

Hans-Peter Jansen hpj at urpla.net
Sun Dec 26 09:08:21 GMT 2010


On Sunday 26 December 2010, 00:45:37 Xavion wrote:
> After further research, not even the following code works:
>
> User.System.bPreferSUdo = bool( str.title( oItems ) )
>
>
> I had to use the following code, which isn't exactly pretty:
>
> User.System.bPreferSUdo = ( oItems == True ) or ( oItems == "true" )
>
>
> The second method takes into account that the value could be coming
> from cache or file.  Are you sure that this is how you want it to be
> for PyQt programmers on Linux from now on?


All values come in as either QVariant wrapped QStrings (v1 API), or 
unicode. If you look into such a config file, you will notice, that 
QSettings hasn't any type hint left behind (apart from those 
unsupported types starting with @). That's usually not a problem in 
C++, where the programmer defines and requests the values' types 
explicitely (or implicitely (casted)). From a dynamically typed 
language, there's nothing, what can be done apart from explicitely 
converting the values to the necessary types.

Pete
-------------- next part --------------
#!/usr/bin/python

import sys

api2 = False
actor = False

if "-v2" in sys.argv[1:]:
    api2 = True
if "-ctor" in sys.argv[1:]:
    actor = True

if api2:
    import sip
    sip.setapi('QVariant', 2)
    sip.setapi('QString', 2)
    print "QString and QVariant API 2 activated"

from PyQt4 import QtGui
from PyQt4 import QtCore


class Widget(QtGui.QWidget):
    def __init__(self, parent = None):
        super(Widget, self).__init__(parent)
        layout = QtGui.QGridLayout()
        settings = QtCore.QSettings()
        settingsTuple = (
            #(key, value, ctor)
            ("str", "hello settings", unicode),
            ("int", 12345678, int),
            ("float", 1234.5678, float),
            ("bool", True, bool),
        )
        row = 0
        for key, value, ctor in settingsTuple:
            layout.addWidget(QtGui.QLabel(key), row, 0)
            if not settings.contains(key):
                settings.setValue(key, value)
            else:
                value = settings.value(key)
                print "setting value of %s: %s type(%s)" % (key, value, type(value))
                if isinstance(value, QtCore.QVariant):
                    value = value.toPyObject()
                    print "QVariant value of %s: %s type(%s)" % (key, value, type(value))
                if actor:
                    print "calling ctor on %s: %s type(%s)" % (key, value, type(ctor(value)))
                    value = ctor(value)

            layout.addWidget(QtGui.QLabel("%s" % value), row, 1)
            layout.addWidget(QtGui.QLabel("(%s)" % type(value)), row, 2)
            row += 1
        self.setLayout(layout)

        
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    app.setOrganizationName("Testing")
    app.setOrganizationDomain("test.example.com")
    app.setApplicationName("TestApp")
    win = Widget()
    win.show()
    sys.exit(app.exec_())


More information about the PyQt mailing list