Fri, 25 Jan 2008 20:48:49 +0100
added a start scrip & cleanups
import os from PyQt4 import QtCore, QtGui, uic def fromVariant(v): _cvrts = {0: lambda x:None, 1: lambda x:x.toBool(), 2: lambda x:x.toInt()[0], 6: lambda x:x.toDouble()[0], 10: lambda x:unicode(x.toString()), 12: lambda x:x.toByteArray(), 21: lambda x:x.toSize(), 22: lambda x:x.toSizeF(), 25: lambda x:x.toPoint(), 26: lambda x:x.toPointF(), } t = v.userType() return _cvrts[t](v) class PreferenceItem(object): _id = 0 def __init__(self, default=None, basetype=None, name=None, description=None): self._default = default self._basetype = basetype if self._basetype is None: self._basetype = self._default.__class__ self._id = "_pref%X"%self.__class__._id self._name = name self._description = description self.__class__._id += 1 def __get__(self, obj, cls): if obj is None: return self try: return obj.getPref(self._id) except Exception, e: #print "humm", e return None def __set__(self, obj, value): obj.setPref(self._id, value) class AbstractPreferences(QtCore.QObject): def __init__(self): QtCore.QObject.__init__(self) self._settings = QtCore.QSettings(QtCore.QSettings.UserScope, self.ORGANISATION, self.APPLICATION) self._prefs = {} for k in dir(self.__class__): item = getattr(self.__class__, k) if isinstance(item, PreferenceItem): self._prefs[item._id] = k def getPref(self, key): key = self._prefs.get(key, key) default = getattr(self.__class__, key)._default if default is not None: default = QtCore.QVariant(default) else: default = QtCore.QVariant() val = self._settings.value(key, default) return fromVariant(val) def setPref(self, key, value): key = self._prefs.get(key, key) self._settings.setValue(key, QtCore.QVariant(value)) def keys(self): return [k for k in self._prefs.values() if not k.startswith('_')] def getName(self, key): item = getattr(self.__class__, key) return item._name def getDescription(self, key): item = getattr(self.__class__, key) return item._description form_class, base_class = uic.loadUiType(os.path.join(os.path.dirname(__file__), "qpreferences_dialog.ui")) class PreferencesEditor(QtGui.QDialog, form_class): def __init__(self, preferences, parent=None): QtGui.QDialog.__init__(self, parent) self.setupUi(self) self._prefs = preferences self.buildUI() def buildUI(self): w = self.centralFrame g = QtGui.QGridLayout(w) p = self._prefs eds = {} self._editors = eds for i, k in enumerate(p.keys()): name = p.getName(k) if not name: name = k l = QtGui.QLabel(name, w) g.addWidget(l, i, 0) if p.getDescription(k): l.setToolTip(p.getDescription(k)) e = QtGui.QLineEdit(w) eds[k] = e g.addWidget(e, i, 1) val = p.getPref(k) if val is None: val = '' if not isinstance(val, basestring): val = unicode(val) e.setText(val) g.addWidget(QtGui.QWidget(w), i+1, 0) g.setRowStretch(i+1,1) g.setColumnStretch(1,1) def accept(self): p=self._prefs for k in p.keys(): newval = unicode(self._editors[k].text()) p.setPref(k, newval) return QtGui.QDialog.accept(self) if __name__ == '__main__': class TestPreferences(AbstractPreferences): ORGANISATION="Logilab" APPLICATION="test_qpref_editor" device = PreferenceItem('/dev/ttyUSB0', name="the device") address = PreferenceItem(5, description="GPIB address of the plotter") _pos = PreferenceItem(None) _size = PreferenceItem(None) _appState = PreferenceItem(None) a = QtGui.QApplication([]) prefs = TestPreferences() w = PreferencesEditor(prefs) w.show() a.exec_()