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
= {}
24 self
.model
.remove_observer (self
)
29 del self
.__model
_to
_view
30 del self
.__view
_to
_model
32 def connect (self
, obj
, signal_str
, *args
):
33 '''Convenience function so that subclasses do not have
34 to import QtCore.SIGNAL.'''
36 if type (signal
) is str:
37 signal
= SIGNAL (signal
)
38 return QObject
.connect ( obj
, signal
, *args
)
40 def SLOT (self
, *args
):
41 '''Default slot to handle all Qt callbacks.
42 This method delegates to callbacks from add_signals.'''
44 widget
= self
.sender()
45 sender
= str (widget
.objectName())
47 if sender
in self
.__callbacks
:
48 model
= self
.__callbacks
[sender
][0]
49 callback
= self
.__callbacks
[sender
][1]
50 callback (model
, *args
)
52 elif sender
in self
.__view
_to
_model
:
53 model
= self
.__view
_to
_model
[sender
][0]
54 model_attr
= self
.__view
_to
_model
[sender
][1]
55 if isinstance (widget
, QTextEdit
):
56 value
= str (widget
.toPlainText())
57 model
.set (model_attr
, value
)
58 elif isinstance (widget
, QLineEdit
):
59 value
= str (widget
.text())
60 model
.set (model_attr
, value
)
62 print ("SLOT(): Unknown widget:",
65 def add_signals (self
, signal_str
, *objects
):
66 '''Connects object's signal to the QObserver.'''
68 self
.connect (obj
, signal_str
, self
.SLOT
)
70 def add_callbacks (self
, model
, callbacks
):
71 '''Registers callbacks that are called in response to GUI events.'''
72 for sender
, callback
in callbacks
.iteritems():
73 self
.__callbacks
[sender
] = ( model
, callback
)
75 def model_to_view (self
, model
, model_attr
, *widget_names
):
76 '''Binds model attributes to qt widgets (model->view)'''
77 self
.add_subject (model
, model_attr
)
78 self
.__model
_to
_view
[model_attr
] = widget_names
79 for widget_name
in widget_names
:
80 self
.__view
_to
_model
[widget_name
] = (model
, model_attr
)
82 def add_actions (self
, model
, model_attr
, callback
):
83 '''Register view actions that are called in response to
84 view changes. (view->model)'''
85 self
.add_subject (model
, model_attr
)
86 self
.__actions
[model_attr
] = callback
88 def subject_changed (self
, model
, attr
, value
):
89 '''Sends a model attribute to the view (model->view)'''
90 if attr
in self
.__model
_to
_view
:
91 for widget_name
in self
.__model
_to
_view
[attr
]:
92 widget
= getattr (self
.view
, widget_name
)
93 if isinstance (widget
, QSpinBox
):
94 widget
.setValue (value
)
95 elif isinstance (widget
, QPixmap
):
97 elif isinstance (widget
, QTextEdit
):
98 widget
.setText (value
)
99 elif isinstance (widget
, QLineEdit
):
100 widget
.setText (value
)
102 print ('subject_changed(): '
106 if attr
not in self
.__actions
: return
108 if attr
in self
.__model
_to
_view
:
109 for widget_name
in self
.__model
_to
_view
[attr
]:
110 widget
= getattr (self
.__view
, widget_name
)
111 widgets
.append (widget
)
112 # Call the model callback w/ the view's widgets as the args
113 self
.__actions
[attr
] (model
, *widgets
)