2 from PyQt4
.QtCore
import QObject
3 from PyQt4
.QtCore
import SIGNAL
4 from PyQt4
.QtGui
import QSpinBox
5 from PyQt4
.QtGui
import QPixmap
6 from PyQt4
.QtGui
import QTextEdit
7 from PyQt4
.QtGui
import QLineEdit
8 from PyQt4
.QtGui
import QListWidget
9 from PyQt4
.QtGui
import QCheckBox
10 from PyQt4
.QtGui
import QFont
11 from PyQt4
.QtGui
import QFontComboBox
13 from observer
import Observer
15 class QObserver(Observer
, QObject
):
17 def __init__(self
, model
, view
):
18 Observer
.__init
__(self
, model
)
19 QObject
.__init
__(self
)
25 self
.__model
_to
_view
= {}
26 self
.__view
_to
_model
= {}
28 def SLOT(self
, *args
):
29 '''Default slot to handle all Qt callbacks.
30 This method delegates to callbacks from add_signals.'''
32 widget
= self
.sender()
33 sender
= str(widget
.objectName())
35 if sender
in self
.__callbacks
:
36 self
.__callbacks
[sender
](*args
)
38 elif sender
in self
.__view
_to
_model
:
40 model_param
= self
.__view
_to
_model
[sender
]
41 if isinstance(widget
, QTextEdit
):
42 value
= str(widget
.toPlainText())
43 model
.set_param(model_param
, value
,
45 elif isinstance(widget
, QLineEdit
):
46 value
= str(widget
.text())
47 model
.set_param(model_param
, value
,
49 elif isinstance(widget
, QCheckBox
):
50 model
.set_param(model_param
, widget
.isChecked(),
52 elif isinstance(widget
, QSpinBox
):
53 model
.set_param(model_param
, widget
.value(),
55 elif isinstance(widget
, QFontComboBox
):
56 value
= unicode(widget
.currentFont().toString())
57 model
.set_param(model_param
, value
,
60 print("SLOT(): Unknown widget:", sender
, widget
)
62 def connect(self
, obj
, signal_str
, *args
):
63 '''Convenience function so that subclasses do not have
64 to import QtCore.SIGNAL.'''
66 if type(signal
) is str:
67 signal
= SIGNAL(signal
)
68 return QObject
.connect(obj
, signal
, *args
)
70 def add_signals(self
, signal_str
, *objects
):
71 '''Connects object's signal to the QObserver.'''
73 self
.connect(obj
, signal_str
, self
.SLOT
)
75 def add_callbacks(self
, **callbacks
):
76 '''Registers callbacks that are called in response to GUI events.'''
77 for sender
, callback
in callbacks
.iteritems():
78 self
.__callbacks
[sender
] = callback
80 def model_to_view(self
, model_param
, *widget_names
):
81 '''Binds model params to qt widgets(model->view)'''
82 self
.__model
_to
_view
[model_param
] = widget_names
83 for widget_name
in widget_names
:
84 self
.__view
_to
_model
[widget_name
] = model_param
86 def add_actions(self
, model_param
, callback
):
87 '''Register view actions that are called in response to
88 view changes.(view->model)'''
89 self
.__actions
[model_param
] = callback
91 def subject_changed(self
, param
, value
):
92 '''Sends a model param to the view(model->view)'''
93 if param
in self
.__model
_to
_view
:
94 for widget_name
in self
.__model
_to
_view
[param
]:
95 widget
= getattr(self
.view
, widget_name
)
96 if isinstance(widget
, QSpinBox
):
97 widget
.setValue(value
)
98 elif isinstance(widget
, QPixmap
):
100 elif isinstance(widget
, QTextEdit
):
101 widget
.setText(value
)
102 elif isinstance(widget
, QLineEdit
):
103 widget
.setText(value
)
104 elif isinstance(widget
, QListWidget
):
106 for i
in value
: widget
.addItem(i
)
107 elif isinstance(widget
, QCheckBox
):
108 widget
.setChecked(value
)
109 elif isinstance(widget
, QFontComboBox
):
110 font
= widget
.currentFont()
111 font
.fromString(value
)
113 print('subject_changed(): '
115 widget_name
, widget
, value
)
117 if param
not in self
.__actions
:
120 if param
in self
.__model
_to
_view
:
121 for widget_name
in self
.__model
_to
_view
[param
]:
122 widget
= getattr(self
.view
, widget_name
)
123 widgets
.append(widget
)
124 # Call the model callback w/ the view's widgets as the args
125 self
.__actions
[param
](*widgets
)
127 def refresh_view(self
):
128 params
= list(self
.__model
_to
_view
.keys())
129 for param
in self
.__actions
.keys():
130 if param
not in params
: params
.append(param
)
131 self
.model
.notify_observers(*params
)