##// END OF EJS Templates
changed close Console behavior to leave Kernel alive
MinRK -
Show More
@@ -1,158 +1,159 b''
1 """ A minimal application using the Qt console-style IPython frontend.
1 """ A minimal application using the Qt console-style IPython frontend.
2 """
2 """
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Imports
5 # Imports
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7
7
8 # Systemm library imports
8 # Systemm library imports
9 from PyQt4 import QtGui
9 from PyQt4 import QtGui
10
10
11 # Local imports
11 # Local imports
12 from IPython.external.argparse import ArgumentParser
12 from IPython.external.argparse import ArgumentParser
13 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
13 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
14 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
14 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
15 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
15 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
16 from IPython.frontend.qt.kernelmanager import QtKernelManager
16 from IPython.frontend.qt.kernelmanager import QtKernelManager
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Constants
19 # Constants
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 LOCALHOST = '127.0.0.1'
22 LOCALHOST = '127.0.0.1'
23
23
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25 # Classes
25 # Classes
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27
27
28 class MainWindow(QtGui.QMainWindow):
28 class MainWindow(QtGui.QMainWindow):
29
29
30 #---------------------------------------------------------------------------
30 #---------------------------------------------------------------------------
31 # 'object' interface
31 # 'object' interface
32 #---------------------------------------------------------------------------
32 #---------------------------------------------------------------------------
33
33
34 def __init__(self, frontend, existing=False):
34 def __init__(self, app, frontend, existing=False):
35 """ Create a MainWindow for the specified FrontendWidget.
35 """ Create a MainWindow for the specified FrontendWidget.
36
36
37 If existing is True, then this Window does not own the Kernel.
37 If existing is True, then this Window does not own the Kernel.
38 """
38 """
39 super(MainWindow, self).__init__()
39 super(MainWindow, self).__init__()
40 self._app = app
40 self._frontend = frontend
41 self._frontend = frontend
41 self._existing = existing
42 self._existing = existing
42 self._frontend.exit_requested.connect(self.close)
43 self._frontend.exit_requested.connect(self.close)
43 self.setCentralWidget(frontend)
44 self.setCentralWidget(frontend)
44
45
45 #---------------------------------------------------------------------------
46 #---------------------------------------------------------------------------
46 # QWidget interface
47 # QWidget interface
47 #---------------------------------------------------------------------------
48 #---------------------------------------------------------------------------
48
49
49 def closeEvent(self, event):
50 def closeEvent(self, event):
50 """ Reimplemented to prompt the user and close the kernel cleanly.
51 """ Reimplemented to prompt the user and close the kernel cleanly.
51 """
52 """
52 kernel_manager = self._frontend.kernel_manager
53 kernel_manager = self._frontend.kernel_manager
53 if kernel_manager and kernel_manager.channels_running:
54 if kernel_manager and kernel_manager.channels_running:
54 title = self.window().windowTitle()
55 title = self.window().windowTitle()
55 reply = QtGui.QMessageBox.question(self, title,
56 reply = QtGui.QMessageBox.question(self, title,
56 "Close just this console, or shutdown the kernel and close "+
57 "Close just this console, or shutdown the kernel and close "+
57 "all windows attached to it?",
58 "all windows attached to it?",
58 'Cancel', 'Close Console', 'Close All')
59 'Cancel', 'Close Console', 'Close All')
59 print reply
60 if reply == 2:
60 if reply == 2:
61 kernel_manager.shutdown_kernel()
61 kernel_manager.shutdown_kernel()
62 #kernel_manager.stop_channels()
62 #kernel_manager.stop_channels()
63 event.accept()
63 event.accept()
64 elif reply == 1:
64 elif reply == 1:
65 if self._existing:
65 if self._existing:
66 # I don't have the Kernel, I can shutdown
66 # I don't have the Kernel, I can shutdown
67 event.accept()
67 event.accept()
68 else:
68 else:
69 # only destroy the Window, save the Kernel
69 # only destroy the Window, save the Kernel
70 self.destroy()
70 self._app.setQuitOnLastWindowClosed(False)
71 self.deleteLater()
71 event.ignore()
72 event.ignore()
72 else:
73 else:
73 event.ignore()
74 event.ignore()
74
75
75 #-----------------------------------------------------------------------------
76 #-----------------------------------------------------------------------------
76 # Main entry point
77 # Main entry point
77 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
78
79
79 def main():
80 def main():
80 """ Entry point for application.
81 """ Entry point for application.
81 """
82 """
82 # Parse command line arguments.
83 # Parse command line arguments.
83 parser = ArgumentParser()
84 parser = ArgumentParser()
84 kgroup = parser.add_argument_group('kernel options')
85 kgroup = parser.add_argument_group('kernel options')
85 kgroup.add_argument('-e', '--existing', action='store_true',
86 kgroup.add_argument('-e', '--existing', action='store_true',
86 help='connect to an existing kernel')
87 help='connect to an existing kernel')
87 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
88 kgroup.add_argument('--ip', type=str, default=LOCALHOST,
88 help='set the kernel\'s IP address [default localhost]')
89 help='set the kernel\'s IP address [default localhost]')
89 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
90 kgroup.add_argument('--xreq', type=int, metavar='PORT', default=0,
90 help='set the XREQ channel port [default random]')
91 help='set the XREQ channel port [default random]')
91 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
92 kgroup.add_argument('--sub', type=int, metavar='PORT', default=0,
92 help='set the SUB channel port [default random]')
93 help='set the SUB channel port [default random]')
93 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
94 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
94 help='set the REP channel port [default random]')
95 help='set the REP channel port [default random]')
95 kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
96 kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
96 help='set the heartbeat port [default: random]')
97 help='set the heartbeat port [default: random]')
97
98
98 egroup = kgroup.add_mutually_exclusive_group()
99 egroup = kgroup.add_mutually_exclusive_group()
99 egroup.add_argument('--pure', action='store_true', help = \
100 egroup.add_argument('--pure', action='store_true', help = \
100 'use a pure Python kernel instead of an IPython kernel')
101 'use a pure Python kernel instead of an IPython kernel')
101 egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
102 egroup.add_argument('--pylab', type=str, metavar='GUI', nargs='?',
102 const='auto', help = \
103 const='auto', help = \
103 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
104 "Pre-load matplotlib and numpy for interactive use. If GUI is not \
104 given, the GUI backend is matplotlib's, otherwise use one of: \
105 given, the GUI backend is matplotlib's, otherwise use one of: \
105 ['tk', 'gtk', 'qt', 'wx', 'inline'].")
106 ['tk', 'gtk', 'qt', 'wx', 'inline'].")
106
107
107 wgroup = parser.add_argument_group('widget options')
108 wgroup = parser.add_argument_group('widget options')
108 wgroup.add_argument('--paging', type=str, default='inside',
109 wgroup.add_argument('--paging', type=str, default='inside',
109 choices = ['inside', 'hsplit', 'vsplit', 'none'],
110 choices = ['inside', 'hsplit', 'vsplit', 'none'],
110 help='set the paging style [default inside]')
111 help='set the paging style [default inside]')
111 wgroup.add_argument('--rich', action='store_true',
112 wgroup.add_argument('--rich', action='store_true',
112 help='enable rich text support')
113 help='enable rich text support')
113 wgroup.add_argument('--gui-completion', action='store_true',
114 wgroup.add_argument('--gui-completion', action='store_true',
114 help='use a GUI widget for tab completion')
115 help='use a GUI widget for tab completion')
115
116
116 args = parser.parse_args()
117 args = parser.parse_args()
117
118
118 # Don't let Qt or ZMQ swallow KeyboardInterupts.
119 # Don't let Qt or ZMQ swallow KeyboardInterupts.
119 import signal
120 import signal
120 signal.signal(signal.SIGINT, signal.SIG_DFL)
121 signal.signal(signal.SIGINT, signal.SIG_DFL)
121
122
122 # Create a KernelManager and start a kernel.
123 # Create a KernelManager and start a kernel.
123 kernel_manager = QtKernelManager(xreq_address=(args.ip, args.xreq),
124 kernel_manager = QtKernelManager(xreq_address=(args.ip, args.xreq),
124 sub_address=(args.ip, args.sub),
125 sub_address=(args.ip, args.sub),
125 rep_address=(args.ip, args.rep),
126 rep_address=(args.ip, args.rep),
126 hb_address=(args.ip, args.hb))
127 hb_address=(args.ip, args.hb))
127 if args.ip == LOCALHOST and not args.existing:
128 if args.ip == LOCALHOST and not args.existing:
128 if args.pure:
129 if args.pure:
129 kernel_manager.start_kernel(ipython=False)
130 kernel_manager.start_kernel(ipython=False)
130 elif args.pylab:
131 elif args.pylab:
131 kernel_manager.start_kernel(pylab=args.pylab)
132 kernel_manager.start_kernel(pylab=args.pylab)
132 else:
133 else:
133 kernel_manager.start_kernel()
134 kernel_manager.start_kernel()
134 kernel_manager.start_channels()
135 kernel_manager.start_channels()
135
136
136 # Create the widget.
137 # Create the widget.
137 app = QtGui.QApplication([])
138 app = QtGui.QApplication([])
138 if args.pure:
139 if args.pure:
139 kind = 'rich' if args.rich else 'plain'
140 kind = 'rich' if args.rich else 'plain'
140 widget = FrontendWidget(kind=kind, paging=args.paging)
141 widget = FrontendWidget(kind=kind, paging=args.paging)
141 elif args.rich or args.pylab:
142 elif args.rich or args.pylab:
142 widget = RichIPythonWidget(paging=args.paging)
143 widget = RichIPythonWidget(paging=args.paging)
143 else:
144 else:
144 widget = IPythonWidget(paging=args.paging)
145 widget = IPythonWidget(paging=args.paging)
145 widget.gui_completion = args.gui_completion
146 widget.gui_completion = args.gui_completion
146 widget.kernel_manager = kernel_manager
147 widget.kernel_manager = kernel_manager
147
148
148 # Create the main window.
149 # Create the main window.
149 window = MainWindow(widget, args.existing)
150 window = MainWindow(app, widget, args.existing)
150 window.setWindowTitle('Python' if args.pure else 'IPython')
151 window.setWindowTitle('Python' if args.pure else 'IPython')
151 window.show()
152 window.show()
152
153
153 # Start the application main loop.
154 # Start the application main loop.
154 app.exec_()
155 app.exec_()
155
156
156
157
157 if __name__ == '__main__':
158 if __name__ == '__main__':
158 main()
159 main()
General Comments 0
You need to be logged in to leave comments. Login now