10 12: lambda x:x.toByteArray(), |
11 12: lambda x:x.toByteArray(), |
11 21: lambda x:x.toSize(), |
12 21: lambda x:x.toSize(), |
12 22: lambda x:x.toSizeF(), |
13 22: lambda x:x.toSizeF(), |
13 25: lambda x:x.toPoint(), |
14 25: lambda x:x.toPoint(), |
14 26: lambda x:x.toPointF(), |
15 26: lambda x:x.toPointF(), |
15 |
16 64: lambda x:QtGui.QFont(x), |
|
17 67: lambda x:QtGui.QColor(x), |
16 } |
18 } |
17 t = v.userType() |
19 t = v.userType() |
18 return _cvrts[t](v) |
20 return _cvrts[t](v) |
19 |
21 |
20 class PreferenceItem(object): |
22 class PreferenceMetaclass(type): |
|
23 _widgets = {} |
|
24 def __init__(cls, name, bases, dct): |
|
25 # called at class creation |
|
26 super(type, cls).__init__(name, bases, dct) |
|
27 if name != "BaseItem": |
|
28 ItemRegister().add(cls) |
|
29 |
|
30 class BaseItem(object): |
|
31 #__metaclass__ = PreferenceMetaclass |
21 _id = 0 |
32 _id = 0 |
22 def __init__(self, default=None, basetype=None, name=None, description=None): |
33 def __init__(self, default=None, name=None, description=None, group=None): |
23 self._default = default |
34 self._default = default |
24 self._basetype = basetype |
35 self._id = BaseItem._id |
25 if self._basetype is None: |
|
26 self._basetype = self._default.__class__ |
|
27 self._id = "_pref%X"%self.__class__._id |
|
28 self._name = name |
36 self._name = name |
29 self._description = description |
37 self._description = description |
30 self.__class__._id += 1 |
38 self._group = group |
|
39 BaseItem._id += 1 |
31 |
40 |
|
41 def validate(self, value): |
|
42 return True |
|
43 |
32 def __get__(self, obj, cls): |
44 def __get__(self, obj, cls): |
33 if obj is None: |
45 if obj is None: #when called from the class, return the Item itself |
34 return self |
46 return self |
35 try: |
47 try: |
36 return obj.getPref(self._id) |
48 return obj.getPref(self._id) |
37 except Exception, e: |
49 except Exception, e: |
38 #print "humm", e |
|
39 return None |
50 return None |
40 |
51 |
41 def __set__(self, obj, value): |
52 def __set__(self, obj, value): |
42 obj.setPref(self._id, value) |
53 obj.setPref(self._id, value) |
|
54 |
|
55 class ItemRegister(AbstractRegister): |
|
56 _registered_type = BaseItem |
|
57 getItem = AbstractRegister.get_class |
|
58 |
|
59 class PointItem(BaseItem): |
|
60 _type = QtCore.QPoint |
|
61 |
|
62 class SizeItem(BaseItem): |
|
63 _type = QtCore.QSize |
|
64 |
|
65 class ByteArrayItem(BaseItem): |
|
66 _type = QtCore.QByteArray |
|
67 |
|
68 class UnicodeItem(BaseItem): |
|
69 _type = unicode |
|
70 def validate(self, value): |
|
71 return isinstance(value, basestring) |
43 |
72 |
|
73 class IntItem(BaseItem): |
|
74 _type = int |
|
75 def __init__(self, default=None, name=None, description=None, group=None, min=None, max=None): |
|
76 BaseItem.__init__(self, default, name, description, group) |
|
77 self._min = min |
|
78 self._max = max |
|
79 |
|
80 def validate(self, value): |
|
81 try: |
|
82 value = self._type(value) |
|
83 except: |
|
84 return False |
|
85 if self._min is not None and value<self._min: |
|
86 return False |
|
87 if self._max is not None and value>self._max: |
|
88 return False |
|
89 return True |
|
90 |
|
91 class ColorItem(BaseItem): |
|
92 _type = QtGui.QColor |
|
93 |
|
94 def validate(self, value): |
|
95 try: |
|
96 self._type(value) |
|
97 return True |
|
98 except: |
|
99 return False |
|
100 |
44 class AbstractPreferences(QtCore.QObject): |
101 class AbstractPreferences(QtCore.QObject): |
45 def __init__(self): |
102 def __init__(self): |
46 QtCore.QObject.__init__(self) |
103 QtCore.QObject.__init__(self) |
47 self._settings = QtCore.QSettings(QtCore.QSettings.UserScope, |
104 self._settings = QtCore.QSettings(QtCore.QSettings.UserScope, |
48 self.ORGANISATION, self.APPLICATION) |
105 self.ORGANISATION, self.APPLICATION) |
49 self._prefs = {} |
106 self._prefs = {} |
|
107 self.groups = [] |
|
108 keys = [] |
50 for k in dir(self.__class__): |
109 for k in dir(self.__class__): |
51 item = getattr(self.__class__, k) |
110 item = self.getItem(k) |
52 if isinstance(item, PreferenceItem): |
111 if isinstance(item, BaseItem): |
53 self._prefs[item._id] = k |
112 keys.append((k,item)) |
54 |
113 keys.sort(key=lambda x: x[1]._id) |
|
114 print [x[1]._id for x in keys] |
|
115 for k, item in keys: |
|
116 self._prefs[item._id] = k |
|
117 if item._group not in self.groups: |
|
118 self.groups.append(item._group) |
|
119 |
|
120 def getItem(self, key): |
|
121 return getattr(self.__class__, key) |
|
122 #return self._prefs.get(key, None) |
|
123 |
55 def getPref(self, key): |
124 def getPref(self, key): |
56 key = self._prefs.get(key, key) |
125 key = self._prefs.get(key, key) |
57 default = getattr(self.__class__, key)._default |
126 default = getattr(self.__class__, key)._default |
58 if default is not None: |
127 if default is not None: |
59 default = QtCore.QVariant(default) |
128 default = QtCore.QVariant(default) |
60 else: |
129 else: |
61 default = QtCore.QVariant() |
130 default = QtCore.QVariant() |
62 val = self._settings.value(key, default) |
131 val = fromVariant(self._settings.value(key, default)) |
63 return fromVariant(val) |
132 return val |
64 |
133 |
65 def setPref(self, key, value): |
134 def setPref(self, key, value): |
66 key = self._prefs.get(key, key) |
135 key = self._prefs.get(key, key) |
67 self._settings.setValue(key, QtCore.QVariant(value)) |
136 self._settings.setValue(key, QtCore.QVariant(value)) |
68 |
137 |
69 def keys(self): |
138 def keys(self, group=None): |
70 return [k for k in self._prefs.values() if not k.startswith('_')] |
139 return [k for k in self._prefs.values() if not k.startswith('_') and self.getItem(k)._group == group] |
71 |
140 |
72 def getName(self, key): |
141 def getName(self, key): |
73 item = getattr(self.__class__, key) |
142 item = getattr(self.__class__, key) |
74 return item._name |
143 return item._name |
75 |
144 |
76 def getDescription(self, key): |
145 def getDescription(self, key): |
77 item = getattr(self.__class__, key) |
146 item = getattr(self.__class__, key) |
78 return item._description |
147 return item._description |
|
148 |
|
149 def __getitem__(self, key): |
|
150 return getattr(self, key) |
79 |
151 |
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_() |
|