##// END OF EJS Templates
Expose configuration to start qtconsole maximized and hide the menu bar on startup
Dan Kilman -
Show More
@@ -1,375 +1,388 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 This is not a complete console app, as subprocess will not be able to receive
3 This is not a complete console app, as subprocess will not be able to receive
4 input, there is no real readline support, among other limitations.
4 input, there is no real readline support, among other limitations.
5
5
6 Authors:
6 Authors:
7
7
8 * Evan Patterson
8 * Evan Patterson
9 * Min RK
9 * Min RK
10 * Erik Tollerud
10 * Erik Tollerud
11 * Fernando Perez
11 * Fernando Perez
12 * Bussonnier Matthias
12 * Bussonnier Matthias
13 * Thomas Kluyver
13 * Thomas Kluyver
14 * Paul Ivanov
14 * Paul Ivanov
15
15
16 """
16 """
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 # stdlib imports
22 # stdlib imports
23 import os
23 import os
24 import signal
24 import signal
25 import sys
25 import sys
26
26
27 # If run on Windows, install an exception hook which pops up a
27 # If run on Windows, install an exception hook which pops up a
28 # message box. Pythonw.exe hides the console, so without this
28 # message box. Pythonw.exe hides the console, so without this
29 # the application silently fails to load.
29 # the application silently fails to load.
30 #
30 #
31 # We always install this handler, because the expectation is for
31 # We always install this handler, because the expectation is for
32 # qtconsole to bring up a GUI even if called from the console.
32 # qtconsole to bring up a GUI even if called from the console.
33 # The old handler is called, so the exception is printed as well.
33 # The old handler is called, so the exception is printed as well.
34 # If desired, check for pythonw with an additional condition
34 # If desired, check for pythonw with an additional condition
35 # (sys.executable.lower().find('pythonw.exe') >= 0).
35 # (sys.executable.lower().find('pythonw.exe') >= 0).
36 if os.name == 'nt':
36 if os.name == 'nt':
37 old_excepthook = sys.excepthook
37 old_excepthook = sys.excepthook
38
38
39 def gui_excepthook(exctype, value, tb):
39 def gui_excepthook(exctype, value, tb):
40 try:
40 try:
41 import ctypes, traceback
41 import ctypes, traceback
42 MB_ICONERROR = 0x00000010L
42 MB_ICONERROR = 0x00000010L
43 title = u'Error starting IPython QtConsole'
43 title = u'Error starting IPython QtConsole'
44 msg = u''.join(traceback.format_exception(exctype, value, tb))
44 msg = u''.join(traceback.format_exception(exctype, value, tb))
45 ctypes.windll.user32.MessageBoxW(0, msg, title, MB_ICONERROR)
45 ctypes.windll.user32.MessageBoxW(0, msg, title, MB_ICONERROR)
46 finally:
46 finally:
47 # Also call the old exception hook to let it do
47 # Also call the old exception hook to let it do
48 # its thing too.
48 # its thing too.
49 old_excepthook(exctype, value, tb)
49 old_excepthook(exctype, value, tb)
50
50
51 sys.excepthook = gui_excepthook
51 sys.excepthook = gui_excepthook
52
52
53 # System library imports
53 # System library imports
54 from IPython.external.qt import QtCore, QtGui
54 from IPython.external.qt import QtCore, QtGui
55
55
56 # Local imports
56 # Local imports
57 from IPython.config.application import boolean_flag, catch_config_error
57 from IPython.config.application import boolean_flag, catch_config_error
58 from IPython.core.application import BaseIPythonApplication
58 from IPython.core.application import BaseIPythonApplication
59 from IPython.core.profiledir import ProfileDir
59 from IPython.core.profiledir import ProfileDir
60 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
60 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
61 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
61 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
62 from IPython.frontend.qt.console import styles
62 from IPython.frontend.qt.console import styles
63 from IPython.frontend.qt.console.mainwindow import MainWindow
63 from IPython.frontend.qt.console.mainwindow import MainWindow
64 from IPython.frontend.qt.client import QtKernelClient
64 from IPython.frontend.qt.client import QtKernelClient
65 from IPython.frontend.qt.manager import QtKernelManager
65 from IPython.frontend.qt.manager import QtKernelManager
66 from IPython.kernel import tunnel_to_kernel, find_connection_file
66 from IPython.kernel import tunnel_to_kernel, find_connection_file
67 from IPython.utils.traitlets import (
67 from IPython.utils.traitlets import (
68 Dict, List, Unicode, CBool, Any
68 Dict, List, Unicode, CBool, Any
69 )
69 )
70 from IPython.kernel.zmq.session import default_secure
70 from IPython.kernel.zmq.session import default_secure
71
71
72 from IPython.frontend.consoleapp import (
72 from IPython.frontend.consoleapp import (
73 IPythonConsoleApp, app_aliases, app_flags, flags, aliases
73 IPythonConsoleApp, app_aliases, app_flags, flags, aliases
74 )
74 )
75
75
76 #-----------------------------------------------------------------------------
76 #-----------------------------------------------------------------------------
77 # Network Constants
77 # Network Constants
78 #-----------------------------------------------------------------------------
78 #-----------------------------------------------------------------------------
79
79
80 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
80 from IPython.utils.localinterfaces import LOCALHOST, LOCAL_IPS
81
81
82 #-----------------------------------------------------------------------------
82 #-----------------------------------------------------------------------------
83 # Globals
83 # Globals
84 #-----------------------------------------------------------------------------
84 #-----------------------------------------------------------------------------
85
85
86 _examples = """
86 _examples = """
87 ipython qtconsole # start the qtconsole
87 ipython qtconsole # start the qtconsole
88 ipython qtconsole --pylab=inline # start with pylab in inline plotting mode
88 ipython qtconsole --pylab=inline # start with pylab in inline plotting mode
89 """
89 """
90
90
91 #-----------------------------------------------------------------------------
91 #-----------------------------------------------------------------------------
92 # Aliases and Flags
92 # Aliases and Flags
93 #-----------------------------------------------------------------------------
93 #-----------------------------------------------------------------------------
94
94
95 # start with copy of flags
95 # start with copy of flags
96 flags = dict(flags)
96 flags = dict(flags)
97 qt_flags = {
97 qt_flags = {
98 'plain' : ({'IPythonQtConsoleApp' : {'plain' : True}},
98 'plain' : ({'IPythonQtConsoleApp' : {'plain' : True}},
99 "Disable rich text support."),
99 "Disable rich text support."),
100 }
100 }
101
101
102 # and app_flags from the Console Mixin
102 # and app_flags from the Console Mixin
103 qt_flags.update(app_flags)
103 qt_flags.update(app_flags)
104 # add frontend flags to the full set
104 # add frontend flags to the full set
105 flags.update(qt_flags)
105 flags.update(qt_flags)
106
106
107 # start with copy of front&backend aliases list
107 # start with copy of front&backend aliases list
108 aliases = dict(aliases)
108 aliases = dict(aliases)
109 qt_aliases = dict(
109 qt_aliases = dict(
110 style = 'IPythonWidget.syntax_style',
110 style = 'IPythonWidget.syntax_style',
111 stylesheet = 'IPythonQtConsoleApp.stylesheet',
111 stylesheet = 'IPythonQtConsoleApp.stylesheet',
112 colors = 'ZMQInteractiveShell.colors',
112 colors = 'ZMQInteractiveShell.colors',
113
113
114 editor = 'IPythonWidget.editor',
114 editor = 'IPythonWidget.editor',
115 paging = 'ConsoleWidget.paging',
115 paging = 'ConsoleWidget.paging',
116 )
116 )
117 # and app_aliases from the Console Mixin
117 # and app_aliases from the Console Mixin
118 qt_aliases.update(app_aliases)
118 qt_aliases.update(app_aliases)
119 qt_aliases.update({'gui-completion':'ConsoleWidget.gui_completion'})
119 qt_aliases.update({'gui-completion':'ConsoleWidget.gui_completion'})
120 # add frontend aliases to the full set
120 # add frontend aliases to the full set
121 aliases.update(qt_aliases)
121 aliases.update(qt_aliases)
122
122
123 # get flags&aliases into sets, and remove a couple that
123 # get flags&aliases into sets, and remove a couple that
124 # shouldn't be scrubbed from backend flags:
124 # shouldn't be scrubbed from backend flags:
125 qt_aliases = set(qt_aliases.keys())
125 qt_aliases = set(qt_aliases.keys())
126 qt_aliases.remove('colors')
126 qt_aliases.remove('colors')
127 qt_flags = set(qt_flags.keys())
127 qt_flags = set(qt_flags.keys())
128
128
129 #-----------------------------------------------------------------------------
129 #-----------------------------------------------------------------------------
130 # Classes
130 # Classes
131 #-----------------------------------------------------------------------------
131 #-----------------------------------------------------------------------------
132
132
133 #-----------------------------------------------------------------------------
133 #-----------------------------------------------------------------------------
134 # IPythonQtConsole
134 # IPythonQtConsole
135 #-----------------------------------------------------------------------------
135 #-----------------------------------------------------------------------------
136
136
137
137
138 class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):
138 class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):
139 name = 'ipython-qtconsole'
139 name = 'ipython-qtconsole'
140
140
141 description = """
141 description = """
142 The IPython QtConsole.
142 The IPython QtConsole.
143
143
144 This launches a Console-style application using Qt. It is not a full
144 This launches a Console-style application using Qt. It is not a full
145 console, in that launched terminal subprocesses will not be able to accept
145 console, in that launched terminal subprocesses will not be able to accept
146 input.
146 input.
147
147
148 The QtConsole supports various extra features beyond the Terminal IPython
148 The QtConsole supports various extra features beyond the Terminal IPython
149 shell, such as inline plotting with matplotlib, via:
149 shell, such as inline plotting with matplotlib, via:
150
150
151 ipython qtconsole --pylab=inline
151 ipython qtconsole --pylab=inline
152
152
153 as well as saving your session as HTML, and printing the output.
153 as well as saving your session as HTML, and printing the output.
154
154
155 """
155 """
156 examples = _examples
156 examples = _examples
157
157
158 classes = [IPythonWidget] + IPythonConsoleApp.classes
158 classes = [IPythonWidget] + IPythonConsoleApp.classes
159 flags = Dict(flags)
159 flags = Dict(flags)
160 aliases = Dict(aliases)
160 aliases = Dict(aliases)
161 frontend_flags = Any(qt_flags)
161 frontend_flags = Any(qt_flags)
162 frontend_aliases = Any(qt_aliases)
162 frontend_aliases = Any(qt_aliases)
163 kernel_client_class = QtKernelClient
163 kernel_client_class = QtKernelClient
164 kernel_manager_class = QtKernelManager
164 kernel_manager_class = QtKernelManager
165
165
166 stylesheet = Unicode('', config=True,
166 stylesheet = Unicode('', config=True,
167 help="path to a custom CSS stylesheet")
167 help="path to a custom CSS stylesheet")
168
168
169 hide_menubar = CBool(False, config=True,
170 help="Start the console window with the menu bar hidden.")
171
172 maximize = CBool(False, config=True,
173 help="Start the console window maximized.")
174
169 plain = CBool(False, config=True,
175 plain = CBool(False, config=True,
170 help="Use a plaintext widget instead of rich text (plain can't print/save).")
176 help="Use a plaintext widget instead of rich text (plain can't print/save).")
171
177
172 def _plain_changed(self, name, old, new):
178 def _plain_changed(self, name, old, new):
173 kind = 'plain' if new else 'rich'
179 kind = 'plain' if new else 'rich'
174 self.config.ConsoleWidget.kind = kind
180 self.config.ConsoleWidget.kind = kind
175 if new:
181 if new:
176 self.widget_factory = IPythonWidget
182 self.widget_factory = IPythonWidget
177 else:
183 else:
178 self.widget_factory = RichIPythonWidget
184 self.widget_factory = RichIPythonWidget
179
185
180 # the factory for creating a widget
186 # the factory for creating a widget
181 widget_factory = Any(RichIPythonWidget)
187 widget_factory = Any(RichIPythonWidget)
182
188
183 def parse_command_line(self, argv=None):
189 def parse_command_line(self, argv=None):
184 super(IPythonQtConsoleApp, self).parse_command_line(argv)
190 super(IPythonQtConsoleApp, self).parse_command_line(argv)
185 self.build_kernel_argv(argv)
191 self.build_kernel_argv(argv)
186
192
187
193
188 def new_frontend_master(self):
194 def new_frontend_master(self):
189 """ Create and return new frontend attached to new kernel, launched on localhost.
195 """ Create and return new frontend attached to new kernel, launched on localhost.
190 """
196 """
191 kernel_manager = self.kernel_manager_class(
197 kernel_manager = self.kernel_manager_class(
192 connection_file=self._new_connection_file(),
198 connection_file=self._new_connection_file(),
193 config=self.config,
199 config=self.config,
194 autorestart=True,
200 autorestart=True,
195 )
201 )
196 # start the kernel
202 # start the kernel
197 kwargs = dict()
203 kwargs = dict()
198 kwargs['extra_arguments'] = self.kernel_argv
204 kwargs['extra_arguments'] = self.kernel_argv
199 kernel_manager.start_kernel(**kwargs)
205 kernel_manager.start_kernel(**kwargs)
200 kernel_manager.client_factory = self.kernel_client_class
206 kernel_manager.client_factory = self.kernel_client_class
201 kernel_client = kernel_manager.client()
207 kernel_client = kernel_manager.client()
202 kernel_client.start_channels(shell=True, iopub=True)
208 kernel_client.start_channels(shell=True, iopub=True)
203 widget = self.widget_factory(config=self.config,
209 widget = self.widget_factory(config=self.config,
204 local_kernel=True)
210 local_kernel=True)
205 self.init_colors(widget)
211 self.init_colors(widget)
206 widget.kernel_manager = kernel_manager
212 widget.kernel_manager = kernel_manager
207 widget.kernel_client = kernel_client
213 widget.kernel_client = kernel_client
208 widget._existing = False
214 widget._existing = False
209 widget._may_close = True
215 widget._may_close = True
210 widget._confirm_exit = self.confirm_exit
216 widget._confirm_exit = self.confirm_exit
211 return widget
217 return widget
212
218
213 def new_frontend_slave(self, current_widget):
219 def new_frontend_slave(self, current_widget):
214 """Create and return a new frontend attached to an existing kernel.
220 """Create and return a new frontend attached to an existing kernel.
215
221
216 Parameters
222 Parameters
217 ----------
223 ----------
218 current_widget : IPythonWidget
224 current_widget : IPythonWidget
219 The IPythonWidget whose kernel this frontend is to share
225 The IPythonWidget whose kernel this frontend is to share
220 """
226 """
221 kernel_client = self.kernel_client_class(
227 kernel_client = self.kernel_client_class(
222 connection_file=current_widget.kernel_client.connection_file,
228 connection_file=current_widget.kernel_client.connection_file,
223 config = self.config,
229 config = self.config,
224 )
230 )
225 kernel_client.load_connection_file()
231 kernel_client.load_connection_file()
226 kernel_client.start_channels()
232 kernel_client.start_channels()
227 widget = self.widget_factory(config=self.config,
233 widget = self.widget_factory(config=self.config,
228 local_kernel=False)
234 local_kernel=False)
229 self.init_colors(widget)
235 self.init_colors(widget)
230 widget._existing = True
236 widget._existing = True
231 widget._may_close = False
237 widget._may_close = False
232 widget._confirm_exit = False
238 widget._confirm_exit = False
233 widget.kernel_client = kernel_client
239 widget.kernel_client = kernel_client
234 widget.kernel_manager = current_widget.kernel_manager
240 widget.kernel_manager = current_widget.kernel_manager
235 return widget
241 return widget
236
242
237 def init_qt_app(self):
243 def init_qt_app(self):
238 # separate from qt_elements, because it must run first
244 # separate from qt_elements, because it must run first
239 self.app = QtGui.QApplication([])
245 self.app = QtGui.QApplication([])
240
246
241 def init_qt_elements(self):
247 def init_qt_elements(self):
242 # Create the widget.
248 # Create the widget.
243
249
244 base_path = os.path.abspath(os.path.dirname(__file__))
250 base_path = os.path.abspath(os.path.dirname(__file__))
245 icon_path = os.path.join(base_path, 'resources', 'icon', 'IPythonConsole.svg')
251 icon_path = os.path.join(base_path, 'resources', 'icon', 'IPythonConsole.svg')
246 self.app.icon = QtGui.QIcon(icon_path)
252 self.app.icon = QtGui.QIcon(icon_path)
247 QtGui.QApplication.setWindowIcon(self.app.icon)
253 QtGui.QApplication.setWindowIcon(self.app.icon)
248
254
249 try:
255 try:
250 ip = self.config.KernelManager.ip
256 ip = self.config.KernelManager.ip
251 except AttributeError:
257 except AttributeError:
252 ip = LOCALHOST
258 ip = LOCALHOST
253 local_kernel = (not self.existing) or ip in LOCAL_IPS
259 local_kernel = (not self.existing) or ip in LOCAL_IPS
254 self.widget = self.widget_factory(config=self.config,
260 self.widget = self.widget_factory(config=self.config,
255 local_kernel=local_kernel)
261 local_kernel=local_kernel)
256 self.init_colors(self.widget)
262 self.init_colors(self.widget)
257 self.widget._existing = self.existing
263 self.widget._existing = self.existing
258 self.widget._may_close = not self.existing
264 self.widget._may_close = not self.existing
259 self.widget._confirm_exit = self.confirm_exit
265 self.widget._confirm_exit = self.confirm_exit
260
266
261 self.widget.kernel_manager = self.kernel_manager
267 self.widget.kernel_manager = self.kernel_manager
262 self.widget.kernel_client = self.kernel_client
268 self.widget.kernel_client = self.kernel_client
263 self.window = MainWindow(self.app,
269 self.window = MainWindow(self.app,
264 confirm_exit=self.confirm_exit,
270 confirm_exit=self.confirm_exit,
265 new_frontend_factory=self.new_frontend_master,
271 new_frontend_factory=self.new_frontend_master,
266 slave_frontend_factory=self.new_frontend_slave,
272 slave_frontend_factory=self.new_frontend_slave,
267 )
273 )
268 self.window.log = self.log
274 self.window.log = self.log
269 self.window.add_tab_with_frontend(self.widget)
275 self.window.add_tab_with_frontend(self.widget)
270 self.window.init_menu_bar()
276 self.window.init_menu_bar()
271
277
278 # Ignore on OSX, where there is always a menu bar
279 if sys.platform != 'darwin' and self.hide_menubar:
280 self.window.menuBar().setVisible(False)
281
272 self.window.setWindowTitle('IPython')
282 self.window.setWindowTitle('IPython')
273
283
274 def init_colors(self, widget):
284 def init_colors(self, widget):
275 """Configure the coloring of the widget"""
285 """Configure the coloring of the widget"""
276 # Note: This will be dramatically simplified when colors
286 # Note: This will be dramatically simplified when colors
277 # are removed from the backend.
287 # are removed from the backend.
278
288
279 # parse the colors arg down to current known labels
289 # parse the colors arg down to current known labels
280 try:
290 try:
281 colors = self.config.ZMQInteractiveShell.colors
291 colors = self.config.ZMQInteractiveShell.colors
282 except AttributeError:
292 except AttributeError:
283 colors = None
293 colors = None
284 try:
294 try:
285 style = self.config.IPythonWidget.syntax_style
295 style = self.config.IPythonWidget.syntax_style
286 except AttributeError:
296 except AttributeError:
287 style = None
297 style = None
288 try:
298 try:
289 sheet = self.config.IPythonWidget.style_sheet
299 sheet = self.config.IPythonWidget.style_sheet
290 except AttributeError:
300 except AttributeError:
291 sheet = None
301 sheet = None
292
302
293 # find the value for colors:
303 # find the value for colors:
294 if colors:
304 if colors:
295 colors=colors.lower()
305 colors=colors.lower()
296 if colors in ('lightbg', 'light'):
306 if colors in ('lightbg', 'light'):
297 colors='lightbg'
307 colors='lightbg'
298 elif colors in ('dark', 'linux'):
308 elif colors in ('dark', 'linux'):
299 colors='linux'
309 colors='linux'
300 else:
310 else:
301 colors='nocolor'
311 colors='nocolor'
302 elif style:
312 elif style:
303 if style=='bw':
313 if style=='bw':
304 colors='nocolor'
314 colors='nocolor'
305 elif styles.dark_style(style):
315 elif styles.dark_style(style):
306 colors='linux'
316 colors='linux'
307 else:
317 else:
308 colors='lightbg'
318 colors='lightbg'
309 else:
319 else:
310 colors=None
320 colors=None
311
321
312 # Configure the style
322 # Configure the style
313 if style:
323 if style:
314 widget.style_sheet = styles.sheet_from_template(style, colors)
324 widget.style_sheet = styles.sheet_from_template(style, colors)
315 widget.syntax_style = style
325 widget.syntax_style = style
316 widget._syntax_style_changed()
326 widget._syntax_style_changed()
317 widget._style_sheet_changed()
327 widget._style_sheet_changed()
318 elif colors:
328 elif colors:
319 # use a default dark/light/bw style
329 # use a default dark/light/bw style
320 widget.set_default_style(colors=colors)
330 widget.set_default_style(colors=colors)
321
331
322 if self.stylesheet:
332 if self.stylesheet:
323 # we got an explicit stylesheet
333 # we got an explicit stylesheet
324 if os.path.isfile(self.stylesheet):
334 if os.path.isfile(self.stylesheet):
325 with open(self.stylesheet) as f:
335 with open(self.stylesheet) as f:
326 sheet = f.read()
336 sheet = f.read()
327 else:
337 else:
328 raise IOError("Stylesheet %r not found." % self.stylesheet)
338 raise IOError("Stylesheet %r not found." % self.stylesheet)
329 if sheet:
339 if sheet:
330 widget.style_sheet = sheet
340 widget.style_sheet = sheet
331 widget._style_sheet_changed()
341 widget._style_sheet_changed()
332
342
333
343
334 def init_signal(self):
344 def init_signal(self):
335 """allow clean shutdown on sigint"""
345 """allow clean shutdown on sigint"""
336 signal.signal(signal.SIGINT, lambda sig, frame: self.exit(-2))
346 signal.signal(signal.SIGINT, lambda sig, frame: self.exit(-2))
337 # need a timer, so that QApplication doesn't block until a real
347 # need a timer, so that QApplication doesn't block until a real
338 # Qt event fires (can require mouse movement)
348 # Qt event fires (can require mouse movement)
339 # timer trick from http://stackoverflow.com/q/4938723/938949
349 # timer trick from http://stackoverflow.com/q/4938723/938949
340 timer = QtCore.QTimer()
350 timer = QtCore.QTimer()
341 # Let the interpreter run each 200 ms:
351 # Let the interpreter run each 200 ms:
342 timer.timeout.connect(lambda: None)
352 timer.timeout.connect(lambda: None)
343 timer.start(200)
353 timer.start(200)
344 # hold onto ref, so the timer doesn't get cleaned up
354 # hold onto ref, so the timer doesn't get cleaned up
345 self._sigint_timer = timer
355 self._sigint_timer = timer
346
356
347 @catch_config_error
357 @catch_config_error
348 def initialize(self, argv=None):
358 def initialize(self, argv=None):
349 self.init_qt_app()
359 self.init_qt_app()
350 super(IPythonQtConsoleApp, self).initialize(argv)
360 super(IPythonQtConsoleApp, self).initialize(argv)
351 IPythonConsoleApp.initialize(self,argv)
361 IPythonConsoleApp.initialize(self,argv)
352 self.init_qt_elements()
362 self.init_qt_elements()
353 self.init_signal()
363 self.init_signal()
354
364
355 def start(self):
365 def start(self):
356
366
357 # draw the window
367 # draw the window
358 self.window.show()
368 if self.maximize:
369 self.window.showMaximized()
370 else:
371 self.window.show()
359 self.window.raise_()
372 self.window.raise_()
360
373
361 # Start the application main loop.
374 # Start the application main loop.
362 self.app.exec_()
375 self.app.exec_()
363
376
364 #-----------------------------------------------------------------------------
377 #-----------------------------------------------------------------------------
365 # Main entry point
378 # Main entry point
366 #-----------------------------------------------------------------------------
379 #-----------------------------------------------------------------------------
367
380
368 def main():
381 def main():
369 app = IPythonQtConsoleApp()
382 app = IPythonQtConsoleApp()
370 app.initialize()
383 app.initialize()
371 app.start()
384 app.start()
372
385
373
386
374 if __name__ == '__main__':
387 if __name__ == '__main__':
375 main()
388 main()
General Comments 0
You need to be logged in to leave comments. Login now