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
):
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
)