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
)
16 model
.add_observer (self
)
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.'''
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
)
53 print ("SLOT(): Unknown widget:",
56 def add_signals (self
, signal_str
, *objects
):
57 '''Connects object's signal to the QObserver.'''
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
):
88 elif isinstance (widget
, QTextEdit
):
89 widget
.setText (value
)
90 elif isinstance (widget
, QLineEdit
):
91 widget
.setText (value
)
93 print ('subject_changed(): '
97 if attr
not in self
.__actions
: return
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
)