pythonguis / pyqtconfig

A PyQt config manager. Keep Qt widgets in sync with an config dictionary and/or QSettings object.
Other
133 stars 33 forks source link

Getting stuck with corrupt setting data for QButtonGroup in QSettingsManager #14

Open stlehmann opened 9 years ago

stlehmann commented 9 years ago

Just had the rare case of having corrupt data in one of my settings. In this specific case it was the mapping of QButtonGroup where the default value is something like [[0, True], [1, False], [2, False]]. But somehow I managed to save [None, [None]] as my settings value. Now everytime I try to add the handler for my ButtonGroup I get following error:

Traceback (most recent call last):
  File "C:/Users/Lehmann/data/python/python34/jsonwatchqt/run_jsonwatchqt.pyw", line 31, in <module>
    w = MainWindow()
  File "C:\Users\Lehmann\data\python\python34\jsonwatchqt\jsonwatchqt\mainwindow.py", line 87, in __init__
    self.plotsettings = PlotSettingsWidget(self.settings, self)
  File "C:\Users\Lehmann\data\python\python34\jsonwatchqt\jsonwatchqt\plotsettings.py", line 89, in __init__
    self.autoscaleButtonGroup)
  File "c:\users\lehmann\data\python\python34\pyqtconfig\pyqtconfig\config.py", line 824, in add_handler
    handler.setter(self._get(key))
  File "c:\users\lehmann\data\python\python34\pyqtconfig\pyqtconfig\config.py", line 568, in _set_QButtonGroup
    for idx, state in v:
TypeError: 'NoneType' object is not iterable

The only way I could help myself was to use another name for the setting. As the exception occurs in __setQButtonGroup I thought about wrapping it in a try ... except right there.

def _set_QButtonGroup(self, v):
    """
        Set the states for all buttons in a group from a list of (index, checked) tuples
    """
    try:
        for idx, state in v:
            self.buttons()[idx].setChecked(state)
    except TypeError:
        pass
mfitzp commented 9 years ago

Thanks for this :+1: Do you know how that value ended up in there?

It probably makes sense to wrap this further up (in the manager itself) so it works for all widgets in case of error. Also worth raising a warning that the set has failed so it shows up in logs.

I'll take a look :)

stlehmann commented 9 years ago

I have no idea how it ended up there. I was playing around with the code of my application a bit but I can' t remember. However it is easily possible that a setting gets corrupted somehow, e.g. by direct manipulation via set(). So it definetly makes sense to wrap it up in the manager for other widgets as well. Returning the default value in case of an error would make sense to me.

:+1: for warning in logs.