plotter/qpreferences.py

changeset 35
3b7a38af5c42
parent 32
59da528bc470
child 36
cb4124e3e75b
equal deleted inserted replaced
34:022e881b758e 35:3b7a38af5c42
1 import os 1 import os
2 from PyQt4 import QtCore, QtGui, uic 2 from PyQt4 import QtCore, QtGui, uic
3 from tools import AbstractRegister
3 4
4 def fromVariant(v): 5 def fromVariant(v):
5 _cvrts = {0: lambda x:None, 6 _cvrts = {0: lambda x:None,
6 1: lambda x:x.toBool(), 7 1: lambda x:x.toBool(),
7 2: lambda x:x.toInt()[0], 8 2: lambda x:x.toInt()[0],
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_()

mercurial