##// END OF EJS Templates
Initial checkin of Qt kernel manager. Began refactor of FrontendWidget.
epatters -
Show More
@@ -0,0 +1,79 b''
1 """ A KernelManager that provides channels that use signals and slots.
2 """
3
4 # System library imports.
5 from PyQt4 import QtCore
6
7 # IPython imports.
8 from IPython.zmq.kernel_manager import KernelManager, SubSocketChannel, \
9 XReqSocketChannel, RepSocketChannel
10
11
12 class QtKernelManager(KernelManager):
13 """ A KernelManager that provides channels that use signals and slots.
14 """
15
16 sub_channel_class = QtSubSocketChannel
17 xreq_channel_class = QtXReqSocketChannel
18 rep_channel_class = QtRepSocketChannel
19
20
21 class QtSubSocketChannel(SubSocketChannel, QtCore.QObject):
22
23 # Emitted when any message is received.
24 message_received = QtCore.pyqtSignal(dict)
25
26 # Emitted when a message of type 'pyout' or 'stdout' is received.
27 output_received = QtCore.pyqtSignal(dict)
28
29 # Emitted when a message of type 'pyerr' or 'stderr' is received.
30 error_received = QtCore.pyqtSignal(dict)
31
32 #---------------------------------------------------------------------------
33 # 'SubSocketChannel' interface
34 #---------------------------------------------------------------------------
35
36 def call_handlers(self, msg):
37 """ Reimplemented to emit signals instead of making callbacks.
38 """
39 # Emit the generic signal.
40 self.message_received.emit(msg)
41
42 # Emit signals for specialized message types.
43 msg_type = msg['msg_type']
44 if msg_type in ('pyout', 'stdout'):
45 self.output_received.emit(msg)
46 elif msg_type in ('pyerr', 'stderr'):
47 self.error_received.emit(msg)
48
49
50 class QtXReqSocketChannel(XReqSocketChannel, QtCore.QObject):
51
52 # Emitted when any message is received.
53 message_received = QtCore.pyqtSignal(dict)
54
55 # Emitted when a reply has been received for the corresponding request type.
56 execute_reply = QtCore.pyqtSignal(dict)
57 complete_reply = QtCore.pyqtSignal(dict)
58 object_info_reply = QtCore.pyqtSignal(dict)
59
60 #---------------------------------------------------------------------------
61 # 'XReqSocketChannel' interface
62 #---------------------------------------------------------------------------
63
64 def call_handlers(self, msg):
65 """ Reimplemented to emit signals instead of making callbacks.
66 """
67 # Emit the generic signal.
68 self.message_received.emit(msg)
69
70 # Emit signals for specialized message types.
71 msg_type = msg['msg_type']
72 signal = getattr(self, msg_type, None)
73 if signal:
74 signal.emit(msg)
75
76
77 class QtRepSocketChannel(RepSocketChannel, QtCore.QObject):
78
79 pass
@@ -5,11 +5,13 b' import time'
5 5 import types
6 6
7 7 # System library imports
8 from IPython.zmq.session import Message, Session
9 8 from pygments.lexers import PythonLexer
10 9 from PyQt4 import QtCore, QtGui
11 10 import zmq
12 11
12 # IPython imports.
13 from IPython.zmq.session import Message, Session
14
13 15 # Local imports
14 16 from call_tip_widget import CallTipWidget
15 17 from completion_lexer import CompletionLexer
@@ -100,23 +102,18 b' class FrontendWidget(HistoryConsoleWidget):'
100 102 # 'QWidget' interface
101 103 #---------------------------------------------------------------------------
102 104
103 def __init__(self, parent=None, session=None, request_socket=None,
104 sub_socket=None):
105 def __init__(self, kernel_manager, parent=None):
105 106 super(FrontendWidget, self).__init__(parent)
106 self.continuation_prompt = '... '
107 107
108 108 self._call_tip_widget = CallTipWidget(self)
109 109 self._compile = CommandCompiler()
110 110 self._completion_lexer = CompletionLexer(PythonLexer())
111 111 self._highlighter = FrontendHighlighter(self)
112 112
113 self.session = Session() if session is None else session
114 self.request_socket = request_socket
115 self.sub_socket = sub_socket
116
117 113 self.document().contentsChange.connect(self._document_contents_change)
118 114
119 self._kernel_connected() # XXX
115 self.continuation_prompt = '... '
116 self.kernel_manager = kernel_manager
120 117
121 118 def focusOutEvent(self, event):
122 119 """ Reimplemented to hide calltips.
@@ -216,6 +213,20 b' class FrontendWidget(HistoryConsoleWidget):'
216 213 """
217 214 self.execute_source('run %s' % path, hidden=hidden)
218 215
216 def _get_kernel_manager(self):
217 """ Returns the current kernel manager.
218 """
219 return self._kernel_manager
220
221 def _set_kernel_manager(self, kernel_manager):
222 """ Sets a new kernel manager, configuring its channels as necessary.
223 """
224 self._kernel_manager = kernel_manager
225 self._sub_channel = kernel_manager.get_sub_channel()
226 self._xreq_channel = kernel_manager.get_xreq_channel()
227
228 kernel_manager = property(_get_kernel_manager, _set_kernel_manager)
229
219 230 #---------------------------------------------------------------------------
220 231 # 'FrontendWidget' protected interface
221 232 #---------------------------------------------------------------------------
@@ -1,9 +1,6 b''
1 1 """Kernel frontend classes.
2 2
3 To do:
4
5 1. Create custom channel subclasses for Qt.
6 2. Create logger to handle debugging and console messages.
3 TODO: Create logger to handle debugging and console messages.
7 4
8 5 """
9 6
@@ -23,6 +20,10 b' class MissingHandlerError(Exception):'
23 20
24 21 class KernelManager(object):
25 22
23 sub_channel_class = SubSocketChannel
24 xreq_channel_class = XReqSocketChannel
25 rep_channel_class = RepSocketChannel
26
26 27 def __init__(self, xreq_addr, sub_addr, rep_addr,
27 28 context=None, session=None):
28 29 self.context = zmq.Context() if context is None else context
@@ -55,15 +56,16 b' class KernelManager(object):'
55 56
56 57 def get_sub_channel(self):
57 58 """Get the SUB socket channel object."""
58 return SubSocketChannel(self.context, self.session, self.sub_addr)
59 return self.sub_channel_class(self.context, self.session, self.sub_addr)
59 60
60 61 def get_xreq_channel(self):
61 62 """Get the REQ socket channel object to make requests of the kernel."""
62 return XReqSocketChannel(self.context, self.session, self.xreq_addr)
63 return self.xreq_channel_class(self.context, self.session,
64 self.xreq_addr)
63 65
64 66 def get_rep_channel(self):
65 67 """Get the REP socket channel object to handle stdin (raw_input)."""
66 return RepSocketChannel(self.context, self.session, self.rep_addr)
68 return self.rep_channel_class(self.context, self.session, self.rep_addr)
67 69
68 70
69 71 class ZmqSocketChannel(Thread):
@@ -186,14 +188,7 b' class XReqSocketChannel(ZmqSocketChannel):'
186 188
187 189 def _handle_recv(self):
188 190 msg = self.socket.recv_json()
189 print "Got reply:", msg
190 try:
191 handler = self.handler_queue.get(False)
192 except Empty:
193 print "Message received with no handler!!!"
194 print msg
195 else:
196 self.call_handler(handler, msg)
191 self.call_handlers(msg)
197 192
198 193 def _handle_send(self):
199 194 try:
@@ -222,13 +217,13 b' class XReqSocketChannel(ZmqSocketChannel):'
222 217 def complete(self, text, line, block=None, callback=None):
223 218 content = dict(text=text, line=line)
224 219 msg = self.session.msg('complete_request', content)
225 return self._queue_request(msg, callback)
220 self._queue_request(msg, callback)
226 221 return msg['header']['msg_id']
227 222
228 223 def object_info(self, oname, callback=None):
229 224 content = dict(oname=oname)
230 225 msg = self.session.msg('object_info_request', content)
231 return self._queue_request(msg, callback)
226 self._queue_request(msg, callback)
232 227 return msg['header']['msg_id']
233 228
234 229 def _find_handler(self, name, callback):
@@ -255,6 +250,15 b' class XReqSocketChannel(ZmqSocketChannel):'
255 250 assert callable(func), "not a callable: %r" % func
256 251 self._overriden_call_handler = func
257 252
253 def call_handlers(self, msg):
254 try:
255 handler = self.handler_queue.get(False)
256 except Empty:
257 print "Message received with no handler!!!"
258 print msg
259 else:
260 self.call_handler(handler, msg)
261
258 262 def call_handler(self, handler, msg):
259 263 if self._overriden_call_handler is not None:
260 264 self._overriden_call_handler(handler, msg)
General Comments 0
You need to be logged in to leave comments. Login now