Show More
@@ -1,196 +1,111 b'' | |||
|
1 | 1 | """A kernel client for in-process kernels.""" |
|
2 | 2 | |
|
3 | 3 | # Copyright (c) IPython Development Team. |
|
4 | 4 | # Distributed under the terms of the Modified BSD License. |
|
5 | 5 | |
|
6 | 6 | from IPython.kernel.channelsabc import ( |
|
7 | 7 | ShellChannelABC, IOPubChannelABC, |
|
8 | 8 | HBChannelABC, StdInChannelABC, |
|
9 | 9 | ) |
|
10 | 10 | |
|
11 | 11 | from .socket import DummySocket |
|
12 | 12 | |
|
13 | 13 | #----------------------------------------------------------------------------- |
|
14 | 14 | # Channel classes |
|
15 | 15 | #----------------------------------------------------------------------------- |
|
16 | 16 | |
|
17 | 17 | class InProcessChannel(object): |
|
18 | 18 | """Base class for in-process channels.""" |
|
19 | 19 | proxy_methods = [] |
|
20 | 20 | |
|
21 | 21 | def __init__(self, client=None): |
|
22 | 22 | super(InProcessChannel, self).__init__() |
|
23 | 23 | self.client = client |
|
24 | 24 | self._is_alive = False |
|
25 | 25 | |
|
26 | 26 | #-------------------------------------------------------------------------- |
|
27 | 27 | # Channel interface |
|
28 | 28 | #-------------------------------------------------------------------------- |
|
29 | 29 | |
|
30 | 30 | def is_alive(self): |
|
31 | 31 | return self._is_alive |
|
32 | 32 | |
|
33 | 33 | def start(self): |
|
34 | 34 | self._is_alive = True |
|
35 | 35 | |
|
36 | 36 | def stop(self): |
|
37 | 37 | self._is_alive = False |
|
38 | 38 | |
|
39 | 39 | def call_handlers(self, msg): |
|
40 | 40 | """ This method is called in the main thread when a message arrives. |
|
41 | 41 | |
|
42 | 42 | Subclasses should override this method to handle incoming messages. |
|
43 | 43 | """ |
|
44 | 44 | raise NotImplementedError('call_handlers must be defined in a subclass.') |
|
45 | 45 | |
|
46 | def flush(self, timeout=1.0): | |
|
47 | pass | |
|
48 | ||
|
46 | 49 | #-------------------------------------------------------------------------- |
|
47 | 50 | # InProcessChannel interface |
|
48 | 51 | #-------------------------------------------------------------------------- |
|
49 | 52 | |
|
50 | 53 | def call_handlers_later(self, *args, **kwds): |
|
51 | 54 | """ Call the message handlers later. |
|
52 | 55 | |
|
53 | 56 | The default implementation just calls the handlers immediately, but this |
|
54 | 57 | method exists so that GUI toolkits can defer calling the handlers until |
|
55 | 58 | after the event loop has run, as expected by GUI frontends. |
|
56 | 59 | """ |
|
57 | 60 | self.call_handlers(*args, **kwds) |
|
58 | 61 | |
|
59 | 62 | def process_events(self): |
|
60 | 63 | """ Process any pending GUI events. |
|
61 | 64 | |
|
62 | 65 | This method will be never be called from a frontend without an event |
|
63 | 66 | loop (e.g., a terminal frontend). |
|
64 | 67 | """ |
|
65 | 68 | raise NotImplementedError |
|
66 | 69 | |
|
67 | 70 | |
|
68 | 71 | class InProcessShellChannel(InProcessChannel): |
|
69 | 72 | """See `IPython.kernel.channels.ShellChannel` for docstrings.""" |
|
70 | 73 | |
|
71 | 74 | # flag for whether execute requests should be allowed to call raw_input |
|
72 | 75 | allow_stdin = True |
|
73 | proxy_methods = [ | |
|
74 | 'execute', | |
|
75 | 'complete', | |
|
76 | 'inspect', | |
|
77 | 'history', | |
|
78 | 'shutdown', | |
|
79 | 'kernel_info', | |
|
80 | ] | |
|
81 | ||
|
82 | #-------------------------------------------------------------------------- | |
|
83 | # ShellChannel interface | |
|
84 | #-------------------------------------------------------------------------- | |
|
85 | ||
|
86 | def execute(self, code, silent=False, store_history=True, | |
|
87 | user_expressions={}, allow_stdin=None): | |
|
88 | if allow_stdin is None: | |
|
89 | allow_stdin = self.allow_stdin | |
|
90 | content = dict(code=code, silent=silent, store_history=store_history, | |
|
91 | user_expressions=user_expressions, | |
|
92 | allow_stdin=allow_stdin) | |
|
93 | msg = self.client.session.msg('execute_request', content) | |
|
94 | self._dispatch_to_kernel(msg) | |
|
95 | return msg['header']['msg_id'] | |
|
96 | ||
|
97 | def complete(self, code, cursor_pos=None): | |
|
98 | if cursor_pos is None: | |
|
99 | cursor_pos = len(code) | |
|
100 | content = dict(code=code, cursor_pos=cursor_pos) | |
|
101 | msg = self.client.session.msg('complete_request', content) | |
|
102 | self._dispatch_to_kernel(msg) | |
|
103 | return msg['header']['msg_id'] | |
|
104 | ||
|
105 | def inspect(self, code, cursor_pos=None, detail_level=0): | |
|
106 | if cursor_pos is None: | |
|
107 | cursor_pos = len(code) | |
|
108 | content = dict(code=code, cursor_pos=cursor_pos, | |
|
109 | detail_level=detail_level, | |
|
110 | ) | |
|
111 | msg = self.client.session.msg('inspect_request', content) | |
|
112 | self._dispatch_to_kernel(msg) | |
|
113 | return msg['header']['msg_id'] | |
|
114 | ||
|
115 | def history(self, raw=True, output=False, hist_access_type='range', **kwds): | |
|
116 | content = dict(raw=raw, output=output, | |
|
117 | hist_access_type=hist_access_type, **kwds) | |
|
118 | msg = self.client.session.msg('history_request', content) | |
|
119 | self._dispatch_to_kernel(msg) | |
|
120 | return msg['header']['msg_id'] | |
|
121 | ||
|
122 | def shutdown(self, restart=False): | |
|
123 | # FIXME: What to do here? | |
|
124 | raise NotImplementedError('Cannot shutdown in-process kernel') | |
|
125 | ||
|
126 | def kernel_info(self): | |
|
127 | """Request kernel info.""" | |
|
128 | msg = self.client.session.msg('kernel_info_request') | |
|
129 | self._dispatch_to_kernel(msg) | |
|
130 | return msg['header']['msg_id'] | |
|
131 | ||
|
132 | #-------------------------------------------------------------------------- | |
|
133 | # Protected interface | |
|
134 | #-------------------------------------------------------------------------- | |
|
135 | ||
|
136 | def _dispatch_to_kernel(self, msg): | |
|
137 | """ Send a message to the kernel and handle a reply. | |
|
138 | """ | |
|
139 | kernel = self.client.kernel | |
|
140 | if kernel is None: | |
|
141 | raise RuntimeError('Cannot send request. No kernel exists.') | |
|
142 | ||
|
143 | stream = DummySocket() | |
|
144 | self.client.session.send(stream, msg) | |
|
145 | msg_parts = stream.recv_multipart() | |
|
146 | kernel.dispatch_shell(stream, msg_parts) | |
|
147 | ||
|
148 | idents, reply_msg = self.client.session.recv(stream, copy=False) | |
|
149 | self.call_handlers_later(reply_msg) | |
|
150 | ||
|
151 | 76 | |
|
152 | 77 | class InProcessIOPubChannel(InProcessChannel): |
|
153 | 78 | """See `IPython.kernel.channels.IOPubChannel` for docstrings.""" |
|
154 | 79 | |
|
155 | def flush(self, timeout=1.0): | |
|
156 | pass | |
|
157 | ||
|
158 | 80 | |
|
159 | 81 | class InProcessStdInChannel(InProcessChannel): |
|
160 | 82 | """See `IPython.kernel.channels.StdInChannel` for docstrings.""" |
|
161 | 83 | |
|
162 | proxy_methods = ['input'] | |
|
163 | ||
|
164 | def input(self, string): | |
|
165 | kernel = self.client.kernel | |
|
166 | if kernel is None: | |
|
167 | raise RuntimeError('Cannot send input reply. No kernel exists.') | |
|
168 | kernel.raw_input_str = string | |
|
169 | 84 | |
|
170 | 85 | |
|
171 | 86 | class InProcessHBChannel(InProcessChannel): |
|
172 | 87 | """See `IPython.kernel.channels.HBChannel` for docstrings.""" |
|
173 | 88 | |
|
174 | 89 | time_to_dead = 3.0 |
|
175 | 90 | |
|
176 | 91 | def __init__(self, *args, **kwds): |
|
177 | 92 | super(InProcessHBChannel, self).__init__(*args, **kwds) |
|
178 | 93 | self._pause = True |
|
179 | 94 | |
|
180 | 95 | def pause(self): |
|
181 | 96 | self._pause = True |
|
182 | 97 | |
|
183 | 98 | def unpause(self): |
|
184 | 99 | self._pause = False |
|
185 | 100 | |
|
186 | 101 | def is_beating(self): |
|
187 | 102 | return not self._pause |
|
188 | 103 | |
|
189 | 104 | #----------------------------------------------------------------------------- |
|
190 | 105 | # ABC Registration |
|
191 | 106 | #----------------------------------------------------------------------------- |
|
192 | 107 | |
|
193 | 108 | ShellChannelABC.register(InProcessShellChannel) |
|
194 | 109 | IOPubChannelABC.register(InProcessIOPubChannel) |
|
195 | 110 | HBChannelABC.register(InProcessHBChannel) |
|
196 | 111 | StdInChannelABC.register(InProcessStdInChannel) |
@@ -1,87 +1,158 b'' | |||
|
1 | 1 | """A client for in-process kernels.""" |
|
2 | 2 | |
|
3 | 3 | #----------------------------------------------------------------------------- |
|
4 | 4 | # Copyright (C) 2012 The IPython Development Team |
|
5 | 5 | # |
|
6 | 6 | # Distributed under the terms of the BSD License. The full license is in |
|
7 | 7 | # the file COPYING, distributed as part of this software. |
|
8 | 8 | #----------------------------------------------------------------------------- |
|
9 | 9 | |
|
10 | 10 | #----------------------------------------------------------------------------- |
|
11 | 11 | # Imports |
|
12 | 12 | #----------------------------------------------------------------------------- |
|
13 | 13 | |
|
14 | 14 | # IPython imports |
|
15 | from IPython.kernel.inprocess.socket import DummySocket | |
|
15 | 16 | from IPython.utils.traitlets import Type, Instance |
|
16 | 17 | from IPython.kernel.clientabc import KernelClientABC |
|
17 | 18 | from IPython.kernel.client import KernelClient |
|
18 | 19 | |
|
19 | 20 | # Local imports |
|
20 | 21 | from .channels import ( |
|
21 | 22 | InProcessShellChannel, |
|
22 | 23 | InProcessIOPubChannel, |
|
23 | 24 | InProcessHBChannel, |
|
24 | 25 | InProcessStdInChannel, |
|
25 | 26 | |
|
26 | 27 | ) |
|
27 | 28 | |
|
28 | 29 | #----------------------------------------------------------------------------- |
|
29 | 30 | # Main kernel Client class |
|
30 | 31 | #----------------------------------------------------------------------------- |
|
31 | 32 | |
|
32 | 33 | class InProcessKernelClient(KernelClient): |
|
33 | 34 | """A client for an in-process kernel. |
|
34 | 35 | |
|
35 | 36 | This class implements the interface of |
|
36 | 37 | `IPython.kernel.clientabc.KernelClientABC` and allows |
|
37 | 38 | (asynchronous) frontends to be used seamlessly with an in-process kernel. |
|
38 | 39 | |
|
39 | 40 | See `IPython.kernel.client.KernelClient` for docstrings. |
|
40 | 41 | """ |
|
41 | 42 | |
|
42 | 43 | # The classes to use for the various channels. |
|
43 | 44 | shell_channel_class = Type(InProcessShellChannel) |
|
44 | 45 | iopub_channel_class = Type(InProcessIOPubChannel) |
|
45 | 46 | stdin_channel_class = Type(InProcessStdInChannel) |
|
46 | 47 | hb_channel_class = Type(InProcessHBChannel) |
|
47 | 48 | |
|
48 | 49 | kernel = Instance('IPython.kernel.inprocess.ipkernel.InProcessKernel') |
|
49 | 50 | |
|
50 | 51 | #-------------------------------------------------------------------------- |
|
51 | 52 | # Channel management methods |
|
52 | 53 | #-------------------------------------------------------------------------- |
|
53 | 54 | |
|
54 | 55 | def start_channels(self, *args, **kwargs): |
|
55 | 56 | super(InProcessKernelClient, self).start_channels(self) |
|
56 | 57 | self.kernel.frontends.append(self) |
|
57 | 58 | |
|
58 | 59 | @property |
|
59 | 60 | def shell_channel(self): |
|
60 | 61 | if self._shell_channel is None: |
|
61 | 62 | self._shell_channel = self.shell_channel_class(self) |
|
62 | 63 | return self._shell_channel |
|
63 | 64 | |
|
64 | 65 | @property |
|
65 | 66 | def iopub_channel(self): |
|
66 | 67 | if self._iopub_channel is None: |
|
67 | 68 | self._iopub_channel = self.iopub_channel_class(self) |
|
68 | 69 | return self._iopub_channel |
|
69 | 70 | |
|
70 | 71 | @property |
|
71 | 72 | def stdin_channel(self): |
|
72 | 73 | if self._stdin_channel is None: |
|
73 | 74 | self._stdin_channel = self.stdin_channel_class(self) |
|
74 | 75 | return self._stdin_channel |
|
75 | 76 | |
|
76 | 77 | @property |
|
77 | 78 | def hb_channel(self): |
|
78 | 79 | if self._hb_channel is None: |
|
79 | 80 | self._hb_channel = self.hb_channel_class(self) |
|
80 | 81 | return self._hb_channel |
|
81 | 82 | |
|
83 | # Methods for sending specific messages | |
|
84 | # ------------------------------------- | |
|
85 | ||
|
86 | def execute(self, code, silent=False, store_history=True, | |
|
87 | user_expressions={}, allow_stdin=None): | |
|
88 | if allow_stdin is None: | |
|
89 | allow_stdin = self.allow_stdin | |
|
90 | content = dict(code=code, silent=silent, store_history=store_history, | |
|
91 | user_expressions=user_expressions, | |
|
92 | allow_stdin=allow_stdin) | |
|
93 | msg = self.session.msg('execute_request', content) | |
|
94 | self._dispatch_to_kernel(msg) | |
|
95 | return msg['header']['msg_id'] | |
|
96 | ||
|
97 | def complete(self, code, cursor_pos=None): | |
|
98 | if cursor_pos is None: | |
|
99 | cursor_pos = len(code) | |
|
100 | content = dict(code=code, cursor_pos=cursor_pos) | |
|
101 | msg = self.session.msg('complete_request', content) | |
|
102 | self._dispatch_to_kernel(msg) | |
|
103 | return msg['header']['msg_id'] | |
|
104 | ||
|
105 | def inspect(self, code, cursor_pos=None, detail_level=0): | |
|
106 | if cursor_pos is None: | |
|
107 | cursor_pos = len(code) | |
|
108 | content = dict(code=code, cursor_pos=cursor_pos, | |
|
109 | detail_level=detail_level, | |
|
110 | ) | |
|
111 | msg = self.session.msg('inspect_request', content) | |
|
112 | self._dispatch_to_kernel(msg) | |
|
113 | return msg['header']['msg_id'] | |
|
114 | ||
|
115 | def history(self, raw=True, output=False, hist_access_type='range', **kwds): | |
|
116 | content = dict(raw=raw, output=output, | |
|
117 | hist_access_type=hist_access_type, **kwds) | |
|
118 | msg = self.session.msg('history_request', content) | |
|
119 | self._dispatch_to_kernel(msg) | |
|
120 | return msg['header']['msg_id'] | |
|
121 | ||
|
122 | def shutdown(self, restart=False): | |
|
123 | # FIXME: What to do here? | |
|
124 | raise NotImplementedError('Cannot shutdown in-process kernel') | |
|
125 | ||
|
126 | def kernel_info(self): | |
|
127 | """Request kernel info.""" | |
|
128 | msg = self.session.msg('kernel_info_request') | |
|
129 | self._dispatch_to_kernel(msg) | |
|
130 | return msg['header']['msg_id'] | |
|
131 | ||
|
132 | def input(self, string): | |
|
133 | if self.kernel is None: | |
|
134 | raise RuntimeError('Cannot send input reply. No kernel exists.') | |
|
135 | self.kernel.raw_input_str = string | |
|
136 | ||
|
137 | ||
|
138 | def _dispatch_to_kernel(self, msg): | |
|
139 | """ Send a message to the kernel and handle a reply. | |
|
140 | """ | |
|
141 | kernel = self.kernel | |
|
142 | if kernel is None: | |
|
143 | raise RuntimeError('Cannot send request. No kernel exists.') | |
|
144 | ||
|
145 | stream = DummySocket() | |
|
146 | self.session.send(stream, msg) | |
|
147 | msg_parts = stream.recv_multipart() | |
|
148 | kernel.dispatch_shell(stream, msg_parts) | |
|
149 | ||
|
150 | idents, reply_msg = self.session.recv(stream, copy=False) | |
|
151 | self.shell_channel.call_handlers_later(reply_msg) | |
|
152 | ||
|
82 | 153 | |
|
83 | 154 | #----------------------------------------------------------------------------- |
|
84 | 155 | # ABC Registration |
|
85 | 156 | #----------------------------------------------------------------------------- |
|
86 | 157 | |
|
87 | 158 | KernelClientABC.register(InProcessKernelClient) |
@@ -1,115 +1,33 b'' | |||
|
1 | 1 | """ Defines an in-process KernelManager with signals and slots. |
|
2 | 2 | """ |
|
3 | 3 | |
|
4 | 4 | # Local imports. |
|
5 | 5 | from IPython.external.qt import QtCore |
|
6 | 6 | from IPython.kernel.inprocess import ( |
|
7 | InProcessShellChannel, InProcessIOPubChannel, InProcessStdInChannel, | |
|
8 | 7 | InProcessHBChannel, InProcessKernelClient, InProcessKernelManager, |
|
9 | 8 | ) |
|
9 | from IPython.kernel.inprocess.channels import InProcessChannel | |
|
10 | 10 | |
|
11 | 11 | from IPython.utils.traitlets import Type |
|
12 | 12 | from .kernel_mixins import ( ChannelQObject, |
|
13 | 13 | QtHBChannelMixin, QtKernelClientMixin, |
|
14 | 14 | QtKernelManagerMixin, |
|
15 | 15 | ) |
|
16 | 16 | |
|
17 | ||
|
18 | class QtInProcessShellChannel(ChannelQObject, InProcessShellChannel): | |
|
19 | # Emitted when a reply has been received for the corresponding request type. | |
|
20 | execute_reply = QtCore.Signal(object) | |
|
21 | complete_reply = QtCore.Signal(object) | |
|
22 | inspect_reply = QtCore.Signal(object) | |
|
23 | history_reply = QtCore.Signal(object) | |
|
24 | kernel_info_reply = QtCore.Signal(object) | |
|
25 | ||
|
26 | def call_handlers(self, msg): | |
|
27 | """ Reimplemented to emit signals instead of making callbacks. | |
|
28 | """ | |
|
29 | # Emit the generic signal. | |
|
30 | self.message_received.emit(msg) | |
|
31 | ||
|
32 | # Emit signals for specialized message types. | |
|
33 | msg_type = msg['header']['msg_type'] | |
|
34 | if msg_type == 'kernel_info_reply': | |
|
35 | self._handle_kernel_info_reply(msg) | |
|
36 | ||
|
37 | signal = getattr(self, msg_type, None) | |
|
38 | if signal: | |
|
39 | signal.emit(msg) | |
|
40 | ||
|
41 | class QtInProcessIOPubChannel(ChannelQObject, InProcessIOPubChannel): | |
|
42 | # Emitted when a message of type 'stream' is received. | |
|
43 | stream_received = QtCore.Signal(object) | |
|
44 | ||
|
45 | # Emitted when a message of type 'execute_input' is received. | |
|
46 | execute_input_received = QtCore.Signal(object) | |
|
47 | ||
|
48 | # Emitted when a message of type 'execute_result' is received. | |
|
49 | execute_result_received = QtCore.Signal(object) | |
|
50 | ||
|
51 | # Emitted when a message of type 'error' is received. | |
|
52 | error_received = QtCore.Signal(object) | |
|
53 | ||
|
54 | # Emitted when a message of type 'display_data' is received | |
|
55 | display_data_received = QtCore.Signal(object) | |
|
56 | ||
|
57 | # Emitted when a crash report message is received from the kernel's | |
|
58 | # last-resort sys.excepthook. | |
|
59 | crash_received = QtCore.Signal(object) | |
|
60 | ||
|
61 | # Emitted when a shutdown is noticed. | |
|
62 | shutdown_reply_received = QtCore.Signal(object) | |
|
63 | ||
|
64 | #--------------------------------------------------------------------------- | |
|
65 | # 'IOPubChannel' interface | |
|
66 | #--------------------------------------------------------------------------- | |
|
67 | ||
|
68 | def call_handlers(self, msg): | |
|
69 | """ Reimplemented to emit signals instead of making callbacks. | |
|
70 | """ | |
|
71 | # Emit the generic signal. | |
|
72 | self.message_received.emit(msg) | |
|
73 | # Emit signals for specialized message types. | |
|
74 | msg_type = msg['header']['msg_type'] | |
|
75 | signal = getattr(self, msg_type + '_received', None) | |
|
76 | if signal: | |
|
77 | signal.emit(msg) | |
|
78 | elif msg_type in ('stdout', 'stderr'): | |
|
79 | self.stream_received.emit(msg) | |
|
80 | ||
|
81 | def flush(self): | |
|
82 | """ Reimplemented to ensure that signals are dispatched immediately. | |
|
83 | """ | |
|
84 | super(QtInProcessIOPubChannel, self).flush() | |
|
85 | QtCore.QCoreApplication.instance().processEvents() | |
|
86 | ||
|
87 | class QtInProcessStdInChannel(ChannelQObject, InProcessStdInChannel): | |
|
88 | # Emitted when an input request is received. | |
|
89 | input_requested = QtCore.Signal(object) | |
|
90 | ||
|
91 | def call_handlers(self, msg): | |
|
92 | """ Reimplemented to emit signals instead of making callbacks. | |
|
93 | """ | |
|
94 | # Emit the generic signal. | |
|
95 | self.message_received.emit(msg) | |
|
96 | ||
|
97 | # Emit signals for specialized message types. | |
|
98 | msg_type = msg['header']['msg_type'] | |
|
99 | if msg_type == 'input_request': | |
|
100 | self.input_requested.emit(msg) | |
|
17 | class QtInProcessChannel(ChannelQObject, InProcessChannel): | |
|
18 | pass | |
|
101 | 19 | |
|
102 | 20 | class QtInProcessHBChannel(QtHBChannelMixin, InProcessHBChannel): |
|
103 | 21 | pass |
|
104 | 22 | |
|
105 | 23 | class QtInProcessKernelClient(QtKernelClientMixin, InProcessKernelClient): |
|
106 | 24 | """ An in-process KernelManager with signals and slots. |
|
107 | 25 | """ |
|
108 | 26 | |
|
109 |
iopub_channel_class = Type(QtInProcess |
|
|
110 |
shell_channel_class = Type(QtInProcess |
|
|
111 |
stdin_channel_class = Type(QtInProcess |
|
|
27 | iopub_channel_class = Type(QtInProcessChannel) | |
|
28 | shell_channel_class = Type(QtInProcessChannel) | |
|
29 | stdin_channel_class = Type(QtInProcessChannel) | |
|
112 | 30 | hb_channel_class = Type(QtInProcessHBChannel) |
|
113 | 31 | |
|
114 | 32 | class QtInProcessKernelManager(QtKernelManagerMixin, InProcessKernelManager): |
|
115 | 33 | client_class = __module__ + '.QtInProcessKernelClient' |
@@ -1,104 +1,105 b'' | |||
|
1 | 1 | """Defines a KernelManager that provides signals and slots.""" |
|
2 | 2 | |
|
3 | 3 | # Copyright (c) IPython Development Team. |
|
4 | 4 | # Distributed under the terms of the Modified BSD License. |
|
5 | 5 | |
|
6 | 6 | from IPython.external.qt import QtCore |
|
7 | 7 | |
|
8 | 8 | from IPython.utils.traitlets import HasTraits, Type |
|
9 | 9 | from .util import MetaQObjectHasTraits, SuperQObject |
|
10 | 10 | |
|
11 | 11 | |
|
12 | 12 | class ChannelQObject(SuperQObject): |
|
13 | 13 | |
|
14 | 14 | # Emitted when the channel is started. |
|
15 | 15 | started = QtCore.Signal() |
|
16 | 16 | |
|
17 | 17 | # Emitted when the channel is stopped. |
|
18 | 18 | stopped = QtCore.Signal() |
|
19 | 19 | |
|
20 | 20 | # Emitted when any message is received. |
|
21 | 21 | message_received = QtCore.Signal(object) |
|
22 | 22 | |
|
23 | #--------------------------------------------------------------------------- | |
|
24 | # Channel interface | |
|
25 | #--------------------------------------------------------------------------- | |
|
26 | ||
|
27 | 23 | def start(self): |
|
28 | 24 | """ Reimplemented to emit signal. |
|
29 | 25 | """ |
|
30 | 26 | super(ChannelQObject, self).start() |
|
31 | 27 | self.started.emit() |
|
32 | 28 | |
|
33 | 29 | def stop(self): |
|
34 | 30 | """ Reimplemented to emit signal. |
|
35 | 31 | """ |
|
36 | 32 | super(ChannelQObject, self).stop() |
|
37 | 33 | self.stopped.emit() |
|
38 | 34 | |
|
39 | #--------------------------------------------------------------------------- | |
|
40 | # InProcessChannel interface | |
|
41 | #--------------------------------------------------------------------------- | |
|
42 | ||
|
43 | 35 | def call_handlers_later(self, *args, **kwds): |
|
44 | 36 | """ Call the message handlers later. |
|
45 | 37 | """ |
|
46 | 38 | do_later = lambda: self.call_handlers(*args, **kwds) |
|
47 | 39 | QtCore.QTimer.singleShot(0, do_later) |
|
48 | 40 | |
|
41 | def call_handlers(self, msg): | |
|
42 | self.message_received.emit(msg) | |
|
43 | ||
|
49 | 44 | def process_events(self): |
|
50 | 45 | """ Process any pending GUI events. |
|
51 | 46 | """ |
|
52 | 47 | QtCore.QCoreApplication.instance().processEvents() |
|
53 | 48 | |
|
49 | def flush(self): | |
|
50 | """ Reimplemented to ensure that signals are dispatched immediately. | |
|
51 | """ | |
|
52 | super(ChannelQObject, self).flush() | |
|
53 | self.process_events() | |
|
54 | ||
|
54 | 55 | |
|
55 | 56 | class QtHBChannelMixin(ChannelQObject): |
|
56 | 57 | |
|
57 | 58 | # Emitted when the kernel has died. |
|
58 | 59 | kernel_died = QtCore.Signal(object) |
|
59 | 60 | |
|
60 | 61 | def call_handlers(self, since_last_heartbeat): |
|
61 | 62 | """ Reimplemented to emit signals instead of making callbacks. |
|
62 | 63 | """ |
|
63 | 64 | self.kernel_died.emit(since_last_heartbeat) |
|
64 | 65 | |
|
65 | 66 | |
|
66 | 67 | class QtKernelRestarterMixin(MetaQObjectHasTraits('NewBase', (HasTraits, SuperQObject), {})): |
|
67 | 68 | |
|
68 | 69 | _timer = None |
|
69 | 70 | |
|
70 | 71 | |
|
71 | 72 | class QtKernelManagerMixin(MetaQObjectHasTraits('NewBase', (HasTraits, SuperQObject), {})): |
|
72 | 73 | """ A KernelClient that provides signals and slots. |
|
73 | 74 | """ |
|
74 | 75 | |
|
75 | 76 | kernel_restarted = QtCore.Signal() |
|
76 | 77 | |
|
77 | 78 | |
|
78 | 79 | class QtKernelClientMixin(MetaQObjectHasTraits('NewBase', (HasTraits, SuperQObject), {})): |
|
79 | 80 | """ A KernelClient that provides signals and slots. |
|
80 | 81 | """ |
|
81 | 82 | |
|
82 | 83 | # Emitted when the kernel client has started listening. |
|
83 | 84 | started_channels = QtCore.Signal() |
|
84 | 85 | |
|
85 | 86 | # Emitted when the kernel client has stopped listening. |
|
86 | 87 | stopped_channels = QtCore.Signal() |
|
87 | 88 | |
|
88 | 89 | #--------------------------------------------------------------------------- |
|
89 | 90 | # 'KernelClient' interface |
|
90 | 91 | #--------------------------------------------------------------------------- |
|
91 | 92 | |
|
92 | 93 | #------ Channel management ------------------------------------------------- |
|
93 | 94 | |
|
94 | 95 | def start_channels(self, *args, **kw): |
|
95 | 96 | """ Reimplemented to emit signal. |
|
96 | 97 | """ |
|
97 | 98 | super(QtKernelClientMixin, self).start_channels(*args, **kw) |
|
98 | 99 | self.started_channels.emit() |
|
99 | 100 | |
|
100 | 101 | def stop_channels(self): |
|
101 | 102 | """ Reimplemented to emit signal. |
|
102 | 103 | """ |
|
103 | 104 | super(QtKernelClientMixin, self).stop_channels() |
|
104 | 105 | self.stopped_channels.emit() |
General Comments 0
You need to be logged in to leave comments.
Login now