Show More
@@ -1,258 +1,260 b'' | |||||
1 | """ Defines a KernelManager that provides signals and slots. |
|
1 | """ Defines a KernelManager that provides signals and slots. | |
2 | """ |
|
2 | """ | |
3 |
|
3 | |||
4 | # System library imports. |
|
4 | # System library imports. | |
5 | from IPython.external.qt import QtCore |
|
5 | from IPython.external.qt import QtCore | |
6 |
|
6 | |||
7 | # IPython imports. |
|
7 | # IPython imports. | |
8 | from IPython.utils.traitlets import Type |
|
8 | from IPython.utils.traitlets import HasTraits, Type | |
9 | from util import SuperQObject |
|
9 | from util import MetaQObjectHasTraits, SuperQObject | |
10 |
|
10 | |||
11 |
|
11 | |||
12 | class ChannelQObject(SuperQObject): |
|
12 | class ChannelQObject(SuperQObject): | |
13 |
|
13 | |||
14 | # Emitted when the channel is started. |
|
14 | # Emitted when the channel is started. | |
15 | started = QtCore.Signal() |
|
15 | started = QtCore.Signal() | |
16 |
|
16 | |||
17 | # Emitted when the channel is stopped. |
|
17 | # Emitted when the channel is stopped. | |
18 | stopped = QtCore.Signal() |
|
18 | stopped = QtCore.Signal() | |
19 |
|
19 | |||
20 | #--------------------------------------------------------------------------- |
|
20 | #--------------------------------------------------------------------------- | |
21 | # Channel interface |
|
21 | # Channel interface | |
22 | #--------------------------------------------------------------------------- |
|
22 | #--------------------------------------------------------------------------- | |
23 |
|
23 | |||
24 | def start(self): |
|
24 | def start(self): | |
25 | """ Reimplemented to emit signal. |
|
25 | """ Reimplemented to emit signal. | |
26 | """ |
|
26 | """ | |
27 | super(ChannelQObject, self).start() |
|
27 | super(ChannelQObject, self).start() | |
28 | self.started.emit() |
|
28 | self.started.emit() | |
29 |
|
29 | |||
30 | def stop(self): |
|
30 | def stop(self): | |
31 | """ Reimplemented to emit signal. |
|
31 | """ Reimplemented to emit signal. | |
32 | """ |
|
32 | """ | |
33 | super(ChannelQObject, self).stop() |
|
33 | super(ChannelQObject, self).stop() | |
34 | self.stopped.emit() |
|
34 | self.stopped.emit() | |
35 |
|
35 | |||
36 | #--------------------------------------------------------------------------- |
|
36 | #--------------------------------------------------------------------------- | |
37 | # EmbeddedChannel interface |
|
37 | # EmbeddedChannel interface | |
38 | #--------------------------------------------------------------------------- |
|
38 | #--------------------------------------------------------------------------- | |
39 |
|
39 | |||
40 | def call_handlers_later(self, *args, **kwds): |
|
40 | def call_handlers_later(self, *args, **kwds): | |
41 | """ Call the message handlers later. |
|
41 | """ Call the message handlers later. | |
42 | """ |
|
42 | """ | |
43 | do_later = lambda: self.call_handlers(*args, **kwds) |
|
43 | do_later = lambda: self.call_handlers(*args, **kwds) | |
44 | QtCore.QTimer.singleShot(0, do_later) |
|
44 | QtCore.QTimer.singleShot(0, do_later) | |
45 |
|
45 | |||
46 | def process_events(self): |
|
46 | def process_events(self): | |
47 | """ Process any pending GUI events. |
|
47 | """ Process any pending GUI events. | |
48 | """ |
|
48 | """ | |
49 | QtCore.QCoreApplication.instance().processEvents() |
|
49 | QtCore.QCoreApplication.instance().processEvents() | |
50 |
|
50 | |||
51 |
|
51 | |||
52 | class QtShellChannelMixin(ChannelQObject): |
|
52 | class QtShellChannelMixin(ChannelQObject): | |
53 |
|
53 | |||
54 | # Emitted when any message is received. |
|
54 | # Emitted when any message is received. | |
55 | message_received = QtCore.Signal(object) |
|
55 | message_received = QtCore.Signal(object) | |
56 |
|
56 | |||
57 | # Emitted when a reply has been received for the corresponding request |
|
57 | # Emitted when a reply has been received for the corresponding request | |
58 | # type. |
|
58 | # type. | |
59 | execute_reply = QtCore.Signal(object) |
|
59 | execute_reply = QtCore.Signal(object) | |
60 | complete_reply = QtCore.Signal(object) |
|
60 | complete_reply = QtCore.Signal(object) | |
61 | object_info_reply = QtCore.Signal(object) |
|
61 | object_info_reply = QtCore.Signal(object) | |
62 | history_reply = QtCore.Signal(object) |
|
62 | history_reply = QtCore.Signal(object) | |
63 |
|
63 | |||
64 | # Emitted when the first reply comes back. |
|
64 | # Emitted when the first reply comes back. | |
65 | first_reply = QtCore.Signal() |
|
65 | first_reply = QtCore.Signal() | |
66 |
|
66 | |||
67 | # Used by the first_reply signal logic to determine if a reply is the |
|
67 | # Used by the first_reply signal logic to determine if a reply is the | |
68 | # first. |
|
68 | # first. | |
69 | _handlers_called = False |
|
69 | _handlers_called = False | |
70 |
|
70 | |||
71 | #--------------------------------------------------------------------------- |
|
71 | #--------------------------------------------------------------------------- | |
72 | # 'ShellSocketChannel' interface |
|
72 | # 'ShellSocketChannel' interface | |
73 | #--------------------------------------------------------------------------- |
|
73 | #--------------------------------------------------------------------------- | |
74 |
|
74 | |||
75 | def call_handlers(self, msg): |
|
75 | def call_handlers(self, msg): | |
76 | """ Reimplemented to emit signals instead of making callbacks. |
|
76 | """ Reimplemented to emit signals instead of making callbacks. | |
77 | """ |
|
77 | """ | |
78 | # Emit the generic signal. |
|
78 | # Emit the generic signal. | |
79 | self.message_received.emit(msg) |
|
79 | self.message_received.emit(msg) | |
80 |
|
80 | |||
81 | # Emit signals for specialized message types. |
|
81 | # Emit signals for specialized message types. | |
82 | msg_type = msg['header']['msg_type'] |
|
82 | msg_type = msg['header']['msg_type'] | |
83 | signal = getattr(self, msg_type, None) |
|
83 | signal = getattr(self, msg_type, None) | |
84 | if signal: |
|
84 | if signal: | |
85 | signal.emit(msg) |
|
85 | signal.emit(msg) | |
86 |
|
86 | |||
87 | if not self._handlers_called: |
|
87 | if not self._handlers_called: | |
88 | self.first_reply.emit() |
|
88 | self.first_reply.emit() | |
89 | self._handlers_called = True |
|
89 | self._handlers_called = True | |
90 |
|
90 | |||
91 | #--------------------------------------------------------------------------- |
|
91 | #--------------------------------------------------------------------------- | |
92 | # 'QtShellChannelMixin' interface |
|
92 | # 'QtShellChannelMixin' interface | |
93 | #--------------------------------------------------------------------------- |
|
93 | #--------------------------------------------------------------------------- | |
94 |
|
94 | |||
95 | def reset_first_reply(self): |
|
95 | def reset_first_reply(self): | |
96 | """ Reset the first_reply signal to fire again on the next reply. |
|
96 | """ Reset the first_reply signal to fire again on the next reply. | |
97 | """ |
|
97 | """ | |
98 | self._handlers_called = False |
|
98 | self._handlers_called = False | |
99 |
|
99 | |||
100 |
|
100 | |||
101 | class QtSubChannelMixin(ChannelQObject): |
|
101 | class QtSubChannelMixin(ChannelQObject): | |
102 |
|
102 | |||
103 | # Emitted when any message is received. |
|
103 | # Emitted when any message is received. | |
104 | message_received = QtCore.Signal(object) |
|
104 | message_received = QtCore.Signal(object) | |
105 |
|
105 | |||
106 | # Emitted when a message of type 'stream' is received. |
|
106 | # Emitted when a message of type 'stream' is received. | |
107 | stream_received = QtCore.Signal(object) |
|
107 | stream_received = QtCore.Signal(object) | |
108 |
|
108 | |||
109 | # Emitted when a message of type 'pyin' is received. |
|
109 | # Emitted when a message of type 'pyin' is received. | |
110 | pyin_received = QtCore.Signal(object) |
|
110 | pyin_received = QtCore.Signal(object) | |
111 |
|
111 | |||
112 | # Emitted when a message of type 'pyout' is received. |
|
112 | # Emitted when a message of type 'pyout' is received. | |
113 | pyout_received = QtCore.Signal(object) |
|
113 | pyout_received = QtCore.Signal(object) | |
114 |
|
114 | |||
115 | # Emitted when a message of type 'pyerr' is received. |
|
115 | # Emitted when a message of type 'pyerr' is received. | |
116 | pyerr_received = QtCore.Signal(object) |
|
116 | pyerr_received = QtCore.Signal(object) | |
117 |
|
117 | |||
118 | # Emitted when a message of type 'display_data' is received |
|
118 | # Emitted when a message of type 'display_data' is received | |
119 | display_data_received = QtCore.Signal(object) |
|
119 | display_data_received = QtCore.Signal(object) | |
120 |
|
120 | |||
121 | # Emitted when a crash report message is received from the kernel's |
|
121 | # Emitted when a crash report message is received from the kernel's | |
122 | # last-resort sys.excepthook. |
|
122 | # last-resort sys.excepthook. | |
123 | crash_received = QtCore.Signal(object) |
|
123 | crash_received = QtCore.Signal(object) | |
124 |
|
124 | |||
125 | # Emitted when a shutdown is noticed. |
|
125 | # Emitted when a shutdown is noticed. | |
126 | shutdown_reply_received = QtCore.Signal(object) |
|
126 | shutdown_reply_received = QtCore.Signal(object) | |
127 |
|
127 | |||
128 | #--------------------------------------------------------------------------- |
|
128 | #--------------------------------------------------------------------------- | |
129 | # 'SubSocketChannel' interface |
|
129 | # 'SubSocketChannel' interface | |
130 | #--------------------------------------------------------------------------- |
|
130 | #--------------------------------------------------------------------------- | |
131 |
|
131 | |||
132 | def call_handlers(self, msg): |
|
132 | def call_handlers(self, msg): | |
133 | """ Reimplemented to emit signals instead of making callbacks. |
|
133 | """ Reimplemented to emit signals instead of making callbacks. | |
134 | """ |
|
134 | """ | |
135 | # Emit the generic signal. |
|
135 | # Emit the generic signal. | |
136 | self.message_received.emit(msg) |
|
136 | self.message_received.emit(msg) | |
137 | # Emit signals for specialized message types. |
|
137 | # Emit signals for specialized message types. | |
138 | msg_type = msg['header']['msg_type'] |
|
138 | msg_type = msg['header']['msg_type'] | |
139 | signal = getattr(self, msg_type + '_received', None) |
|
139 | signal = getattr(self, msg_type + '_received', None) | |
140 | if signal: |
|
140 | if signal: | |
141 | signal.emit(msg) |
|
141 | signal.emit(msg) | |
142 | elif msg_type in ('stdout', 'stderr'): |
|
142 | elif msg_type in ('stdout', 'stderr'): | |
143 | self.stream_received.emit(msg) |
|
143 | self.stream_received.emit(msg) | |
144 |
|
144 | |||
145 | def flush(self): |
|
145 | def flush(self): | |
146 | """ Reimplemented to ensure that signals are dispatched immediately. |
|
146 | """ Reimplemented to ensure that signals are dispatched immediately. | |
147 | """ |
|
147 | """ | |
148 | super(QtSubChannelMixin, self).flush() |
|
148 | super(QtSubChannelMixin, self).flush() | |
149 | QtCore.QCoreApplication.instance().processEvents() |
|
149 | QtCore.QCoreApplication.instance().processEvents() | |
150 |
|
150 | |||
151 |
|
151 | |||
152 | class QtStdInChannelMixin(ChannelQObject): |
|
152 | class QtStdInChannelMixin(ChannelQObject): | |
153 |
|
153 | |||
154 | # Emitted when any message is received. |
|
154 | # Emitted when any message is received. | |
155 | message_received = QtCore.Signal(object) |
|
155 | message_received = QtCore.Signal(object) | |
156 |
|
156 | |||
157 | # Emitted when an input request is received. |
|
157 | # Emitted when an input request is received. | |
158 | input_requested = QtCore.Signal(object) |
|
158 | input_requested = QtCore.Signal(object) | |
159 |
|
159 | |||
160 | #--------------------------------------------------------------------------- |
|
160 | #--------------------------------------------------------------------------- | |
161 | # 'StdInSocketChannel' interface |
|
161 | # 'StdInSocketChannel' interface | |
162 | #--------------------------------------------------------------------------- |
|
162 | #--------------------------------------------------------------------------- | |
163 |
|
163 | |||
164 | def call_handlers(self, msg): |
|
164 | def call_handlers(self, msg): | |
165 | """ Reimplemented to emit signals instead of making callbacks. |
|
165 | """ Reimplemented to emit signals instead of making callbacks. | |
166 | """ |
|
166 | """ | |
167 | # Emit the generic signal. |
|
167 | # Emit the generic signal. | |
168 | self.message_received.emit(msg) |
|
168 | self.message_received.emit(msg) | |
169 |
|
169 | |||
170 | # Emit signals for specialized message types. |
|
170 | # Emit signals for specialized message types. | |
171 | msg_type = msg['header']['msg_type'] |
|
171 | msg_type = msg['header']['msg_type'] | |
172 | if msg_type == 'input_request': |
|
172 | if msg_type == 'input_request': | |
173 | self.input_requested.emit(msg) |
|
173 | self.input_requested.emit(msg) | |
174 |
|
174 | |||
175 |
|
175 | |||
176 | class QtHBChannelMixin(ChannelQObject): |
|
176 | class QtHBChannelMixin(ChannelQObject): | |
177 |
|
177 | |||
178 | # Emitted when the kernel has died. |
|
178 | # Emitted when the kernel has died. | |
179 | kernel_died = QtCore.Signal(object) |
|
179 | kernel_died = QtCore.Signal(object) | |
180 |
|
180 | |||
181 | #--------------------------------------------------------------------------- |
|
181 | #--------------------------------------------------------------------------- | |
182 | # 'HBSocketChannel' interface |
|
182 | # 'HBSocketChannel' interface | |
183 | #--------------------------------------------------------------------------- |
|
183 | #--------------------------------------------------------------------------- | |
184 |
|
184 | |||
185 | def call_handlers(self, since_last_heartbeat): |
|
185 | def call_handlers(self, since_last_heartbeat): | |
186 | """ Reimplemented to emit signals instead of making callbacks. |
|
186 | """ Reimplemented to emit signals instead of making callbacks. | |
187 | """ |
|
187 | """ | |
188 | # Emit the generic signal. |
|
188 | # Emit the generic signal. | |
189 | self.kernel_died.emit(since_last_heartbeat) |
|
189 | self.kernel_died.emit(since_last_heartbeat) | |
190 |
|
190 | |||
191 |
|
191 | |||
192 |
class QtKernelManagerMixin( |
|
192 | class QtKernelManagerMixin(HasTraits, SuperQObject): | |
193 | """ A KernelManager that provides signals and slots. |
|
193 | """ A KernelManager that provides signals and slots. | |
194 | """ |
|
194 | """ | |
195 |
|
195 | |||
|
196 | __metaclass__ = MetaQObjectHasTraits | |||
|
197 | ||||
196 | # Emitted when the kernel manager has started listening. |
|
198 | # Emitted when the kernel manager has started listening. | |
197 | started_kernel = QtCore.Signal() |
|
199 | started_kernel = QtCore.Signal() | |
198 |
|
200 | |||
199 | # Emitted when the kernel manager has started listening. |
|
201 | # Emitted when the kernel manager has started listening. | |
200 | started_channels = QtCore.Signal() |
|
202 | started_channels = QtCore.Signal() | |
201 |
|
203 | |||
202 | # Emitted when the kernel manager has stopped listening. |
|
204 | # Emitted when the kernel manager has stopped listening. | |
203 | stopped_channels = QtCore.Signal() |
|
205 | stopped_channels = QtCore.Signal() | |
204 |
|
206 | |||
205 | # Use Qt-specific channel classes that emit signals. |
|
207 | # Use Qt-specific channel classes that emit signals. | |
206 | sub_channel_class = Type(QtSubChannelMixin) |
|
208 | sub_channel_class = Type(QtSubChannelMixin) | |
207 | shell_channel_class = Type(QtShellChannelMixin) |
|
209 | shell_channel_class = Type(QtShellChannelMixin) | |
208 | stdin_channel_class = Type(QtStdInChannelMixin) |
|
210 | stdin_channel_class = Type(QtStdInChannelMixin) | |
209 | hb_channel_class = Type(QtHBChannelMixin) |
|
211 | hb_channel_class = Type(QtHBChannelMixin) | |
210 |
|
212 | |||
211 | #--------------------------------------------------------------------------- |
|
213 | #--------------------------------------------------------------------------- | |
212 | # 'KernelManager' interface |
|
214 | # 'KernelManager' interface | |
213 | #--------------------------------------------------------------------------- |
|
215 | #--------------------------------------------------------------------------- | |
214 |
|
216 | |||
215 | #------ Kernel process management ------------------------------------------ |
|
217 | #------ Kernel process management ------------------------------------------ | |
216 |
|
218 | |||
217 | def start_kernel(self, *args, **kw): |
|
219 | def start_kernel(self, *args, **kw): | |
218 | """ Reimplemented for proper heartbeat management. |
|
220 | """ Reimplemented for proper heartbeat management. | |
219 | """ |
|
221 | """ | |
220 | if self._shell_channel is not None: |
|
222 | if self._shell_channel is not None: | |
221 | self._shell_channel.reset_first_reply() |
|
223 | self._shell_channel.reset_first_reply() | |
222 | super(QtKernelManagerMixin, self).start_kernel(*args, **kw) |
|
224 | super(QtKernelManagerMixin, self).start_kernel(*args, **kw) | |
223 | self.started_kernel.emit() |
|
225 | self.started_kernel.emit() | |
224 |
|
226 | |||
225 | #------ Channel management ------------------------------------------------- |
|
227 | #------ Channel management ------------------------------------------------- | |
226 |
|
228 | |||
227 | def start_channels(self, *args, **kw): |
|
229 | def start_channels(self, *args, **kw): | |
228 | """ Reimplemented to emit signal. |
|
230 | """ Reimplemented to emit signal. | |
229 | """ |
|
231 | """ | |
230 | super(QtKernelManagerMixin, self).start_channels(*args, **kw) |
|
232 | super(QtKernelManagerMixin, self).start_channels(*args, **kw) | |
231 | self.started_channels.emit() |
|
233 | self.started_channels.emit() | |
232 |
|
234 | |||
233 | def stop_channels(self): |
|
235 | def stop_channels(self): | |
234 | """ Reimplemented to emit signal. |
|
236 | """ Reimplemented to emit signal. | |
235 | """ |
|
237 | """ | |
236 | super(QtKernelManagerMixin, self).stop_channels() |
|
238 | super(QtKernelManagerMixin, self).stop_channels() | |
237 | self.stopped_channels.emit() |
|
239 | self.stopped_channels.emit() | |
238 |
|
240 | |||
239 | @property |
|
241 | @property | |
240 | def shell_channel(self): |
|
242 | def shell_channel(self): | |
241 | """ Reimplemented for proper heartbeat management. |
|
243 | """ Reimplemented for proper heartbeat management. | |
242 | """ |
|
244 | """ | |
243 | if self._shell_channel is None: |
|
245 | if self._shell_channel is None: | |
244 | self._shell_channel = super(QtKernelManagerMixin,self).shell_channel |
|
246 | self._shell_channel = super(QtKernelManagerMixin,self).shell_channel | |
245 | self._shell_channel.first_reply.connect(self._first_reply) |
|
247 | self._shell_channel.first_reply.connect(self._first_reply) | |
246 | return self._shell_channel |
|
248 | return self._shell_channel | |
247 |
|
249 | |||
248 | #--------------------------------------------------------------------------- |
|
250 | #--------------------------------------------------------------------------- | |
249 | # Protected interface |
|
251 | # Protected interface | |
250 | #--------------------------------------------------------------------------- |
|
252 | #--------------------------------------------------------------------------- | |
251 |
|
253 | |||
252 | def _first_reply(self): |
|
254 | def _first_reply(self): | |
253 | """ Unpauses the heartbeat channel when the first reply is received on |
|
255 | """ Unpauses the heartbeat channel when the first reply is received on | |
254 | the execute channel. Note that this will *not* start the heartbeat |
|
256 | the execute channel. Note that this will *not* start the heartbeat | |
255 | channel if it is not already running! |
|
257 | channel if it is not already running! | |
256 | """ |
|
258 | """ | |
257 | if self._hb_channel is not None: |
|
259 | if self._hb_channel is not None: | |
258 | self._hb_channel.unpause() |
|
260 | self._hb_channel.unpause() |
@@ -1,37 +1,33 b'' | |||||
1 | """ Defines an embedded KernelManager that provides signals and slots. |
|
1 | """ Defines an embedded KernelManager that provides signals and slots. | |
2 | """ |
|
2 | """ | |
3 |
|
3 | |||
4 | # Local imports. |
|
4 | # Local imports. | |
5 | from IPython.embedded.kernelmanager import \ |
|
5 | from IPython.embedded.kernelmanager import \ | |
6 | ShellEmbeddedChannel, SubEmbeddedChannel, StdInEmbeddedChannel, \ |
|
6 | ShellEmbeddedChannel, SubEmbeddedChannel, StdInEmbeddedChannel, \ | |
7 | HBEmbeddedChannel, EmbeddedKernelManager |
|
7 | HBEmbeddedChannel, EmbeddedKernelManager | |
8 | from IPython.utils.traitlets import Type |
|
8 | from IPython.utils.traitlets import Type | |
9 | from base_kernelmanager import QtShellChannelMixin, QtSubChannelMixin, \ |
|
9 | from base_kernelmanager import QtShellChannelMixin, QtSubChannelMixin, \ | |
10 | QtStdInChannelMixin, QtHBChannelMixin, QtKernelManagerMixin |
|
10 | QtStdInChannelMixin, QtHBChannelMixin, QtKernelManagerMixin | |
11 | from util import MetaQObjectHasTraits, SuperQObject |
|
|||
12 |
|
11 | |||
13 |
|
12 | |||
14 | class QtShellEmbeddedChannel(QtShellChannelMixin, ShellEmbeddedChannel): |
|
13 | class QtShellEmbeddedChannel(QtShellChannelMixin, ShellEmbeddedChannel): | |
15 | pass |
|
14 | pass | |
16 |
|
15 | |||
17 | class QtSubEmbeddedChannel(QtSubChannelMixin, SubEmbeddedChannel): |
|
16 | class QtSubEmbeddedChannel(QtSubChannelMixin, SubEmbeddedChannel): | |
18 | pass |
|
17 | pass | |
19 |
|
18 | |||
20 | class QtStdInEmbeddedChannel(QtStdInChannelMixin, StdInEmbeddedChannel): |
|
19 | class QtStdInEmbeddedChannel(QtStdInChannelMixin, StdInEmbeddedChannel): | |
21 | pass |
|
20 | pass | |
22 |
|
21 | |||
23 | class QtHBEmbeddedChannel(QtHBChannelMixin, HBEmbeddedChannel): |
|
22 | class QtHBEmbeddedChannel(QtHBChannelMixin, HBEmbeddedChannel): | |
24 | pass |
|
23 | pass | |
25 |
|
24 | |||
26 |
|
25 | |||
27 | class QtEmbeddedKernelManager(QtKernelManagerMixin, |
|
26 | class QtEmbeddedKernelManager(QtKernelManagerMixin, EmbeddedKernelManager): | |
28 | EmbeddedKernelManager, SuperQObject): |
|
|||
29 | """ An embedded KernelManager that provides signals and slots. |
|
27 | """ An embedded KernelManager that provides signals and slots. | |
30 | """ |
|
28 | """ | |
31 |
|
29 | |||
32 | __metaclass__ = MetaQObjectHasTraits |
|
|||
33 |
|
||||
34 | sub_channel_class = Type(QtSubEmbeddedChannel) |
|
30 | sub_channel_class = Type(QtSubEmbeddedChannel) | |
35 | shell_channel_class = Type(QtShellEmbeddedChannel) |
|
31 | shell_channel_class = Type(QtShellEmbeddedChannel) | |
36 | stdin_channel_class = Type(QtStdInEmbeddedChannel) |
|
32 | stdin_channel_class = Type(QtStdInEmbeddedChannel) | |
37 | hb_channel_class = Type(QtHBEmbeddedChannel) |
|
33 | hb_channel_class = Type(QtHBEmbeddedChannel) |
@@ -1,35 +1,32 b'' | |||||
1 | """ Defines a KernelManager that provides signals and slots. |
|
1 | """ Defines a KernelManager that provides signals and slots. | |
2 | """ |
|
2 | """ | |
3 |
|
3 | |||
4 | # Local imports. |
|
4 | # Local imports. | |
5 | from IPython.utils.traitlets import Type |
|
5 | from IPython.utils.traitlets import Type | |
6 | from IPython.zmq.kernelmanager import ShellSocketChannel, SubSocketChannel, \ |
|
6 | from IPython.zmq.kernelmanager import ShellSocketChannel, SubSocketChannel, \ | |
7 | StdInSocketChannel, HBSocketChannel, KernelManager |
|
7 | StdInSocketChannel, HBSocketChannel, KernelManager | |
8 | from base_kernelmanager import QtShellChannelMixin, QtSubChannelMixin, \ |
|
8 | from base_kernelmanager import QtShellChannelMixin, QtSubChannelMixin, \ | |
9 | QtStdInChannelMixin, QtHBChannelMixin, QtKernelManagerMixin |
|
9 | QtStdInChannelMixin, QtHBChannelMixin, QtKernelManagerMixin | |
10 | from util import MetaQObjectHasTraits, SuperQObject |
|
|||
11 |
|
10 | |||
12 |
|
11 | |||
13 | class QtShellSocketChannel(QtShellChannelMixin, ShellSocketChannel): |
|
12 | class QtShellSocketChannel(QtShellChannelMixin, ShellSocketChannel): | |
14 | pass |
|
13 | pass | |
15 |
|
14 | |||
16 | class QtSubSocketChannel(QtSubChannelMixin, SubSocketChannel): |
|
15 | class QtSubSocketChannel(QtSubChannelMixin, SubSocketChannel): | |
17 | pass |
|
16 | pass | |
18 |
|
17 | |||
19 | class QtStdInSocketChannel(QtStdInChannelMixin, StdInSocketChannel): |
|
18 | class QtStdInSocketChannel(QtStdInChannelMixin, StdInSocketChannel): | |
20 | pass |
|
19 | pass | |
21 |
|
20 | |||
22 | class QtHBSocketChannel(QtHBChannelMixin, HBSocketChannel): |
|
21 | class QtHBSocketChannel(QtHBChannelMixin, HBSocketChannel): | |
23 | pass |
|
22 | pass | |
24 |
|
23 | |||
25 |
|
24 | |||
26 |
class QtKernelManager(QtKernelManagerMixin, KernelManager |
|
25 | class QtKernelManager(QtKernelManagerMixin, KernelManager): | |
27 | """ A KernelManager that provides signals and slots. |
|
26 | """ A KernelManager that provides signals and slots. | |
28 | """ |
|
27 | """ | |
29 |
|
28 | |||
30 | __metaclass__ = MetaQObjectHasTraits |
|
|||
31 |
|
||||
32 | sub_channel_class = Type(QtSubSocketChannel) |
|
29 | sub_channel_class = Type(QtSubSocketChannel) | |
33 | shell_channel_class = Type(QtShellSocketChannel) |
|
30 | shell_channel_class = Type(QtShellSocketChannel) | |
34 | stdin_channel_class = Type(QtStdInSocketChannel) |
|
31 | stdin_channel_class = Type(QtStdInSocketChannel) | |
35 | hb_channel_class = Type(QtHBSocketChannel) |
|
32 | hb_channel_class = Type(QtHBSocketChannel) |
@@ -1,106 +1,106 b'' | |||||
1 | """ Defines miscellaneous Qt-related helper classes and functions. |
|
1 | """ Defines miscellaneous Qt-related helper classes and functions. | |
2 | """ |
|
2 | """ | |
3 |
|
3 | |||
4 | # Standard library imports. |
|
4 | # Standard library imports. | |
5 | import inspect |
|
5 | import inspect | |
6 |
|
6 | |||
7 | # System library imports. |
|
7 | # System library imports. | |
8 | from IPython.external.qt import QtCore, QtGui |
|
8 | from IPython.external.qt import QtCore, QtGui | |
9 |
|
9 | |||
10 | # IPython imports. |
|
10 | # IPython imports. | |
11 | from IPython.utils.traitlets import HasTraits, TraitType |
|
11 | from IPython.utils.traitlets import HasTraits, TraitType | |
12 |
|
12 | |||
13 | #----------------------------------------------------------------------------- |
|
13 | #----------------------------------------------------------------------------- | |
14 | # Metaclasses |
|
14 | # Metaclasses | |
15 | #----------------------------------------------------------------------------- |
|
15 | #----------------------------------------------------------------------------- | |
16 |
|
16 | |||
17 | MetaHasTraits = type(HasTraits) |
|
17 | MetaHasTraits = type(HasTraits) | |
18 | MetaQObject = type(QtCore.QObject) |
|
18 | MetaQObject = type(QtCore.QObject) | |
19 |
|
19 | |||
20 | class MetaQObjectHasTraits(MetaQObject, MetaHasTraits): |
|
20 | class MetaQObjectHasTraits(MetaQObject, MetaHasTraits): | |
21 | """ A metaclass that inherits from the metaclasses of HasTraits and QObject. |
|
21 | """ A metaclass that inherits from the metaclasses of HasTraits and QObject. | |
22 |
|
22 | |||
23 | Using this metaclass allows a class to inherit from both HasTraits and |
|
23 | Using this metaclass allows a class to inherit from both HasTraits and | |
24 | QObject. Using SuperQObject instead of QObject is highly recommended. See |
|
24 | QObject. Using SuperQObject instead of QObject is highly recommended. See | |
25 | QtKernelManager for an example. |
|
25 | QtKernelManager for an example. | |
26 | """ |
|
26 | """ | |
27 | def __new__(mcls, name, bases, classdict): |
|
27 | def __new__(mcls, name, bases, classdict): | |
28 | # FIXME: this duplicates the code from MetaHasTraits. |
|
28 | # FIXME: this duplicates the code from MetaHasTraits. | |
29 | # I don't think a super() call will help me here. |
|
29 | # I don't think a super() call will help me here. | |
30 | for k,v in classdict.iteritems(): |
|
30 | for k,v in classdict.iteritems(): | |
31 | if isinstance(v, TraitType): |
|
31 | if isinstance(v, TraitType): | |
32 | v.name = k |
|
32 | v.name = k | |
33 | elif inspect.isclass(v): |
|
33 | elif inspect.isclass(v): | |
34 | if issubclass(v, TraitType): |
|
34 | if issubclass(v, TraitType): | |
35 | vinst = v() |
|
35 | vinst = v() | |
36 | vinst.name = k |
|
36 | vinst.name = k | |
37 | classdict[k] = vinst |
|
37 | classdict[k] = vinst | |
38 | cls = MetaQObject.__new__(mcls, name, bases, classdict) |
|
38 | cls = MetaQObject.__new__(mcls, name, bases, classdict) | |
39 | return cls |
|
39 | return cls | |
40 |
|
40 | |||
41 | def __init__(mcls, name, bases, classdict): |
|
41 | def __init__(mcls, name, bases, classdict): | |
42 | # Note: super() did not work, so we explicitly call these. |
|
42 | # Note: super() did not work, so we explicitly call these. | |
43 | MetaQObject.__init__(mcls, name, bases, classdict) |
|
43 | MetaQObject.__init__(mcls, name, bases, classdict) | |
44 | MetaHasTraits.__init__(mcls, name, bases, classdict) |
|
44 | MetaHasTraits.__init__(mcls, name, bases, classdict) | |
45 |
|
45 | |||
46 | #----------------------------------------------------------------------------- |
|
46 | #----------------------------------------------------------------------------- | |
47 | # Classes |
|
47 | # Classes | |
48 | #----------------------------------------------------------------------------- |
|
48 | #----------------------------------------------------------------------------- | |
49 |
|
49 | |||
50 | class SuperQObject(QtCore.QObject): |
|
50 | class SuperQObject(QtCore.QObject): | |
51 | """ Permits the use of super() in class hierarchies that contain QObject. |
|
51 | """ Permits the use of super() in class hierarchies that contain QObject. | |
52 |
|
52 | |||
53 | Unlike QObject, SuperQObject does not accept a QObject parent. If it did, |
|
53 | Unlike QObject, SuperQObject does not accept a QObject parent. If it did, | |
54 | super could not be emulated properly (all other classes in the heierarchy |
|
54 | super could not be emulated properly (all other classes in the heierarchy | |
55 | would have to accept the parent argument--they don't, of course, because |
|
55 | would have to accept the parent argument--they don't, of course, because | |
56 | they don't inherit QObject.) |
|
56 | they don't inherit QObject.) | |
57 |
|
57 | |||
58 | This class is primarily useful for attaching signals to existing non-Qt |
|
58 | This class is primarily useful for attaching signals to existing non-Qt | |
59 | classes. See QtKernelManager for an example. |
|
59 | classes. See QtKernelManagerMixin for an example. | |
60 | """ |
|
60 | """ | |
61 |
|
61 | |||
62 | def __new__(cls, *args, **kw): |
|
62 | def __new__(cls, *args, **kw): | |
63 | # We initialize QObject as early as possible. Without this, Qt complains |
|
63 | # We initialize QObject as early as possible. Without this, Qt complains | |
64 | # if SuperQObject is not the first class in the super class list. |
|
64 | # if SuperQObject is not the first class in the super class list. | |
65 | inst = QtCore.QObject.__new__(cls) |
|
65 | inst = QtCore.QObject.__new__(cls) | |
66 | QtCore.QObject.__init__(inst) |
|
66 | QtCore.QObject.__init__(inst) | |
67 | return inst |
|
67 | return inst | |
68 |
|
68 | |||
69 | def __init__(self, *args, **kw): |
|
69 | def __init__(self, *args, **kw): | |
70 | # Emulate super by calling the next method in the MRO, if there is one. |
|
70 | # Emulate super by calling the next method in the MRO, if there is one. | |
71 | mro = self.__class__.mro() |
|
71 | mro = self.__class__.mro() | |
72 | for qt_class in QtCore.QObject.mro(): |
|
72 | for qt_class in QtCore.QObject.mro(): | |
73 | mro.remove(qt_class) |
|
73 | mro.remove(qt_class) | |
74 | next_index = mro.index(SuperQObject) + 1 |
|
74 | next_index = mro.index(SuperQObject) + 1 | |
75 | if next_index < len(mro): |
|
75 | if next_index < len(mro): | |
76 | mro[next_index].__init__(self, *args, **kw) |
|
76 | mro[next_index].__init__(self, *args, **kw) | |
77 |
|
77 | |||
78 | #----------------------------------------------------------------------------- |
|
78 | #----------------------------------------------------------------------------- | |
79 | # Functions |
|
79 | # Functions | |
80 | #----------------------------------------------------------------------------- |
|
80 | #----------------------------------------------------------------------------- | |
81 |
|
81 | |||
82 | def get_font(family, fallback=None): |
|
82 | def get_font(family, fallback=None): | |
83 | """Return a font of the requested family, using fallback as alternative. |
|
83 | """Return a font of the requested family, using fallback as alternative. | |
84 |
|
84 | |||
85 | If a fallback is provided, it is used in case the requested family isn't |
|
85 | If a fallback is provided, it is used in case the requested family isn't | |
86 | found. If no fallback is given, no alternative is chosen and Qt's internal |
|
86 | found. If no fallback is given, no alternative is chosen and Qt's internal | |
87 | algorithms may automatically choose a fallback font. |
|
87 | algorithms may automatically choose a fallback font. | |
88 |
|
88 | |||
89 | Parameters |
|
89 | Parameters | |
90 | ---------- |
|
90 | ---------- | |
91 | family : str |
|
91 | family : str | |
92 | A font name. |
|
92 | A font name. | |
93 | fallback : str |
|
93 | fallback : str | |
94 | A font name. |
|
94 | A font name. | |
95 |
|
95 | |||
96 | Returns |
|
96 | Returns | |
97 | ------- |
|
97 | ------- | |
98 | font : QFont object |
|
98 | font : QFont object | |
99 | """ |
|
99 | """ | |
100 | font = QtGui.QFont(family) |
|
100 | font = QtGui.QFont(family) | |
101 | # Check whether we got what we wanted using QFontInfo, since exactMatch() |
|
101 | # Check whether we got what we wanted using QFontInfo, since exactMatch() | |
102 | # is overly strict and returns false in too many cases. |
|
102 | # is overly strict and returns false in too many cases. | |
103 | font_info = QtGui.QFontInfo(font) |
|
103 | font_info = QtGui.QFontInfo(font) | |
104 | if fallback is not None and font_info.family() != family: |
|
104 | if fallback is not None and font_info.family() != family: | |
105 | font = QtGui.QFont(fallback) |
|
105 | font = QtGui.QFont(fallback) | |
106 | return font |
|
106 | return font |
General Comments 0
You need to be logged in to leave comments.
Login now