Make things look nicer on MacOS
[ugit.git] / py / qobserver.py
blob0228c16d94fa34211c1ee45d647a7e4e9cc35d83
1 #!/usr/bin/env python
2 from PyQt4.QtCore import QObject
3 from PyQt4.QtCore import SIGNAL
4 from PyQt4.QtGui import QSpinBox, QPixmap, QTextEdit, QLineEdit
6 from observer import Observer
8 class QObserver (Observer, QObject):
10 def __init__ (self, model, view):
11 Observer.__init__ (self)
12 QObject.__init__ (self)
14 self.model = model
15 self.view = view
16 model.add_observer (self)
18 self.__actions= {}
19 self.__callbacks = {}
20 self.__model_to_view = {}
21 self.__view_to_model = {}
23 def connect (self, obj, signal_str, *args):
24 '''Convenience function so that subclasses do not have
25 to import QtCore.SIGNAL.'''
26 signal = signal_str
27 if type (signal) is str:
28 signal = SIGNAL (signal)
29 return QObject.connect ( obj, signal, *args)
31 def SLOT (self, *args):
32 '''Default slot to handle all Qt callbacks.
33 This method delegates to callbacks from add_signals.'''
35 widget = self.sender()
36 sender = str (widget.objectName())
38 if sender in self.__callbacks:
39 model = self.__callbacks[sender][0]
40 callback = self.__callbacks[sender][1]
41 callback (model, *args)
43 elif sender in self.__view_to_model:
44 model = self.__view_to_model[sender][0]
45 model_attr = self.__view_to_model[sender][1]
46 if isinstance (widget, QTextEdit):
47 value = str (widget.toPlainText())
48 model.set (model_attr, value)
49 elif isinstance (widget, QLineEdit):
50 value = str (widget.text())
51 model.set (model_attr, value)
52 else:
53 print ("SLOT(): Unknown widget:",
54 sender, widget)
56 def add_signals (self, signal_str, *objects):
57 '''Connects object's signal to the QObserver.'''
58 for obj in objects:
59 self.connect (obj, signal_str, self.SLOT)
61 def add_callbacks (self, model, callbacks):
62 '''Registers callbacks that are called in response to GUI events.'''
63 for sender, callback in callbacks.iteritems():
64 self.__callbacks[sender] = ( model, callback )
66 def model_to_view (self, model, model_attr, *widget_names):
67 '''Binds model attributes to qt widgets (model->view)'''
68 self.add_subject (model, model_attr)
69 self.__model_to_view[model_attr] = widget_names
70 for widget_name in widget_names:
71 self.__view_to_model[widget_name] = (model, model_attr)
73 def add_actions (self, model, model_attr, callback):
74 '''Register view actions that are called in response to
75 view changes. (view->model)'''
76 self.add_subject (model, model_attr)
77 self.__actions[model_attr] = callback
79 def subject_changed (self, model, attr, value):
80 '''Sends a model attribute to the view (model->view)'''
81 if attr in self.__model_to_view:
82 for widget_name in self.__model_to_view[attr]:
83 widget = getattr (self.view, widget_name)
84 if isinstance (widget, QSpinBox):
85 widget.setValue (value)
86 elif isinstance (widget, QPixmap):
87 widget.load (value)
88 elif isinstance (widget, QTextEdit):
89 widget.setText (value)
90 elif isinstance (widget, QLineEdit):
91 widget.setText (value)
92 else:
93 print ('subject_changed(): '
94 + 'Unknown widget:',
95 widget_name, widget)
97 if attr not in self.__actions: return
98 widgets = []
99 if attr in self.__model_to_view:
100 for widget_name in self.__model_to_view[attr]:
101 widget = getattr (self.__view, widget_name)
102 widgets.append (widget)
103 # Call the model callback w/ the view's widgets as the args
104 self.__actions[attr] (model, *widgets)