qpreferences.py

changeset 23
cb97962a1ae9
equal deleted inserted replaced
22:b2f4646161be 23:cb97962a1ae9
1 import os
2 from PyQt4 import QtCore, QtGui, uic
3
4 def fromVariant(v):
5 _cvrts = {0: lambda x:None,
6 1: lambda x:x.toBool(),
7 2: lambda x:x.toInt()[0],
8 6: lambda x:x.toDouble()[0],
9 10: lambda x:unicode(x.toString()),
10 12: lambda x:x.toByteArray(),
11 21: lambda x:x.toSize(),
12 22: lambda x:x.toSizeF(),
13 25: lambda x:x.toPoint(),
14 26: lambda x:x.toPointF(),
15
16 }
17 t = v.userType()
18 return _cvrts[t](v)
19
20 class PreferenceItem(object):
21 _id = 0
22 def __init__(self, default=None, basetype=None, name=None, description=None):
23 self._default = default
24 self._basetype = basetype
25 if self._basetype is None:
26 self._basetype = self._default.__class__
27 self._id = "_pref%X"%self.__class__._id
28 self._name = name
29 self._description = description
30 self.__class__._id += 1
31
32 def __get__(self, obj, cls):
33 if obj is None:
34 return self
35 try:
36 return obj.getPref(self._id)
37 except Exception, e:
38 #print "humm", e
39 return None
40
41 def __set__(self, obj, value):
42 obj.setPref(self._id, value)
43
44 class AbstractPreferences(QtCore.QObject):
45 def __init__(self):
46 QtCore.QObject.__init__(self)
47 self._settings = QtCore.QSettings(QtCore.QSettings.UserScope,
48 self.ORGANISATION, self.APPLICATION)
49 self._prefs = {}
50 for k in dir(self.__class__):
51 item = getattr(self.__class__, k)
52 if isinstance(item, PreferenceItem):
53 self._prefs[item._id] = k
54
55 def getPref(self, key):
56 key = self._prefs.get(key, key)
57 default = getattr(self.__class__, key)._default
58 if default is not None:
59 default = QtCore.QVariant(default)
60 else:
61 default = QtCore.QVariant()
62 val = self._settings.value(key, default)
63 return fromVariant(val)
64
65 def setPref(self, key, value):
66 key = self._prefs.get(key, key)
67 self._settings.setValue(key, QtCore.QVariant(value))
68
69 def keys(self):
70 return [k for k in self._prefs.values() if not k.startswith('_')]
71
72 def getName(self, key):
73 item = getattr(self.__class__, key)
74 return item._name
75
76 def getDescription(self, key):
77 item = getattr(self.__class__, key)
78 return item._description
79
80 form_class, base_class = uic.loadUiType(os.path.join(os.path.dirname(__file__), "qpreferences_dialog.ui"))
81
82 class PreferencesEditor(QtGui.QDialog, form_class):
83 def __init__(self, preferences, parent=None):
84 QtGui.QDialog.__init__(self, parent)
85 self.setupUi(self)
86 self._prefs = preferences
87 self.buildUI()
88
89 def buildUI(self):
90 w = self.centralFrame
91 g = QtGui.QGridLayout(w)
92 p = self._prefs
93 eds = {}
94 self._editors = eds
95 for i, k in enumerate(p.keys()):
96 name = p.getName(k)
97 if not name:
98 name = k
99 l = QtGui.QLabel(name, w)
100 g.addWidget(l, i, 0)
101 if p.getDescription(k):
102 l.setToolTip(p.getDescription(k))
103
104 e = QtGui.QLineEdit(w)
105 eds[k] = e
106 g.addWidget(e, i, 1)
107 val = p.getPref(k)
108 if val is None:
109 val = ''
110 if not isinstance(val, basestring):
111 val = unicode(val)
112 e.setText(val)
113
114 g.addWidget(QtGui.QWidget(w), i+1, 0)
115 g.setRowStretch(i+1,1)
116 g.setColumnStretch(1,1)
117
118 def accept(self):
119 p=self._prefs
120 for k in p.keys():
121 newval = unicode(self._editors[k].text())
122 p.setPref(k, newval)
123 return QtGui.QDialog.accept(self)
124
125 if __name__ == '__main__':
126 class TestPreferences(AbstractPreferences):
127 ORGANISATION="Logilab"
128 APPLICATION="test_qpref_editor"
129
130 device = PreferenceItem('/dev/ttyUSB0', name="the device")
131 address = PreferenceItem(5, description="GPIB address of the plotter")
132 _pos = PreferenceItem(None)
133 _size = PreferenceItem(None)
134 _appState = PreferenceItem(None)
135
136 a = QtGui.QApplication([])
137
138 prefs = TestPreferences()
139 w = PreferencesEditor(prefs)
140 w.show()
141 a.exec_()

mercurial