##// END OF EJS Templates
add LazyConfigValue...
add LazyConfigValue exposes container methods on container traits, to be lazily evaluated. Specifically: - append, extend, insert on lists - update on dicts - update, add on sets

File last commit:

r12591:5d0418a8
r12795:c2f47ddb
Show More
qtconsoleapp.py
382 lines | 13.0 KiB | text/x-python | PythonLexer
epatters
Created a proper IPython script from the console frontend demo.
r2801 """ A minimal application using the Qt console-style IPython frontend.
MinRK
code updates per review of PR #454
r4021
This is not a complete console app, as subprocess will not be able to receive
input, there is no real readline support, among other limitations.
Authors:
* Evan Patterson
* Min RK
* Erik Tollerud
* Fernando Perez
MinRK
Split Qt MainWindow into its own file
r5136 * Bussonnier Matthias
* Thomas Kluyver
Paul Ivanov
refactoring common code out of qtconsole
r5603 * Paul Ivanov
MinRK
code updates per review of PR #454
r4021
epatters
* The SVG payload matplotlib backend now works....
r2758 """
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
MinRK
QtConsole now uses newapp
r3971 # stdlib imports
import os
import signal
import sys
Mark Wiebe
Fix for issue #1437, unfriendly windows qtconsole error handling
r6168 # If run on Windows, install an exception hook which pops up a
# message box. Pythonw.exe hides the console, so without this
# the application silently fails to load.
#
# We always install this handler, because the expectation is for
# qtconsole to bring up a GUI even if called from the console.
# The old handler is called, so the exception is printed as well.
# If desired, check for pythonw with an additional condition
# (sys.executable.lower().find('pythonw.exe') >= 0).
if os.name == 'nt':
old_excepthook = sys.excepthook
def gui_excepthook(exctype, value, tb):
try:
import ctypes, traceback
MB_ICONERROR = 0x00000010L
title = u'Error starting IPython QtConsole'
msg = u''.join(traceback.format_exception(exctype, value, tb))
ctypes.windll.user32.MessageBoxW(0, msg, title, MB_ICONERROR)
finally:
# Also call the old exception hook to let it do
# its thing too.
old_excepthook(exctype, value, tb)
sys.excepthook = gui_excepthook
MinRK
QtConsole now uses newapp
r3971 # System library imports
MinRK
improve cleanup of connection files...
r5609 from IPython.external.qt import QtCore, QtGui
Evan Patterson
Paved the way for PySide support....
r3304
epatters
* The SVG payload matplotlib backend now works....
r2758 # Local imports
Thomas Kluyver
Remove unused imports in IPython.qt
r11131 from IPython.config.application import catch_config_error
MinRK
move ipcluster create|list to `ipython profile create|list`...
r4024 from IPython.core.application import BaseIPythonApplication
Fernando Perez
Fix all imports for Qt console.
r11022 from IPython.qt.console.ipython_widget import IPythonWidget
from IPython.qt.console.rich_ipython_widget import RichIPythonWidget
from IPython.qt.console import styles
from IPython.qt.console.mainwindow import MainWindow
from IPython.qt.client import QtKernelClient
from IPython.qt.manager import QtKernelManager
MinRK
QtConsole now uses newapp
r3971 from IPython.utils.traitlets import (
Thomas Kluyver
Remove unused imports in IPython.qt
r11131 Dict, Unicode, CBool, Any
MinRK
QtConsole now uses newapp
r3971 )
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604
Fernando Perez
Fix all imports for Qt console.
r11022 from IPython.consoleapp import (
MinRK
rename IPythonMixinConsoleApp to IPythonConsoleApp...
r5618 IPythonConsoleApp, app_aliases, app_flags, flags, aliases
Paul Ivanov
refactoring common code out of qtconsole
r5603 )
MinRK
QtConsole now uses newapp
r3971
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
MinRK
Possible fix for GH-169
r3144 # Network Constants
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591 from IPython.utils.localinterfaces import is_local_ip
epatters
Added arguments to the Qt console frontend script for connecting to an existing kernel and for specifying an IP and specific ports.
r2823
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
Brian Granger
More work on adding examples to help strings.
r4216 # Globals
#-----------------------------------------------------------------------------
_examples = """
Matthias BUSSONNIER
remove again a few other occurences
r11784 ipython qtconsole # start the qtconsole
ipython qtconsole --matplotlib=inline # start with matplotlib inline plotting mode
Brian Granger
More work on adding examples to help strings.
r4216 """
#-----------------------------------------------------------------------------
MinRK
QtConsole now uses newapp
r3971 # Aliases and Flags
epatters
* Moved shutdown_kernel method from FrontendWidget to KernelManager....
r2961 #-----------------------------------------------------------------------------
epatters
* The SVG payload matplotlib backend now works....
r2758
MinRK
update flags&aliases for two-process apps...
r5610 # start with copy of flags
flags = dict(flags)
MinRK
command-line pass...
r4247 qt_flags = {
MinRK
remove references to removed pykernel and associated pure flag
r6806 'plain' : ({'IPythonQtConsoleApp' : {'plain' : True}},
MinRK
QtConsole now uses newapp
r3971 "Disable rich text support."),
MinRK
command-line pass...
r4247 }
Matthias BUSSONNIER
new completer for qtconsole....
r7389
MinRK
update flags&aliases for two-process apps...
r5610 # and app_flags from the Console Mixin
qt_flags.update(app_flags)
# add frontend flags to the full set
MinRK
command-line pass...
r4247 flags.update(qt_flags)
MinRK
QtConsole now uses newapp
r3971
MinRK
update flags&aliases for two-process apps...
r5610 # start with copy of front&backend aliases list
aliases = dict(aliases)
MinRK
command-line pass...
r4247 qt_aliases = dict(
MinRK
QtConsole now uses newapp
r3971 style = 'IPythonWidget.syntax_style',
stylesheet = 'IPythonQtConsoleApp.stylesheet',
colors = 'ZMQInteractiveShell.colors',
editor = 'IPythonWidget.editor',
MinRK
fix qtconsole description...
r4222 paging = 'ConsoleWidget.paging',
MinRK
command-line pass...
r4247 )
MinRK
update flags&aliases for two-process apps...
r5610 # and app_aliases from the Console Mixin
qt_aliases.update(app_aliases)
Matthias BUSSONNIER
new completer for qtconsole....
r7389 qt_aliases.update({'gui-completion':'ConsoleWidget.gui_completion'})
MinRK
update flags&aliases for two-process apps...
r5610 # add frontend aliases to the full set
MinRK
command-line pass...
r4247 aliases.update(qt_aliases)
MinRK
fix qtconsole description...
r4222
MinRK
update flags&aliases for two-process apps...
r5610 # get flags&aliases into sets, and remove a couple that
# shouldn't be scrubbed from backend flags:
qt_aliases = set(qt_aliases.keys())
qt_aliases.remove('colors')
qt_flags = set(qt_flags.keys())
MinRK
Split Qt MainWindow into its own file
r5136 #-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
MinRK
QtConsole now uses newapp
r3971
#-----------------------------------------------------------------------------
# IPythonQtConsole
#-----------------------------------------------------------------------------
Brian Granger
Command line examples added for non-parallel apps.
r4215
MinRK
rename IPythonMixinConsoleApp to IPythonConsoleApp...
r5618 class IPythonQtConsoleApp(BaseIPythonApplication, IPythonConsoleApp):
MinRK
QtConsole now uses newapp
r3971 name = 'ipython-qtconsole'
Matthias BUSSONNIER
reorganise menu...
r5060
MinRK
code updates per review of PR #454
r4021 description = """
The IPython QtConsole.
This launches a Console-style application using Qt. It is not a full
MinRK
fix qtconsole description...
r4222 console, in that launched terminal subprocesses will not be able to accept
input.
The QtConsole supports various extra features beyond the Terminal IPython
shell, such as inline plotting with matplotlib, via:
Matthias BUSSONNIER
remove again a few other occurences
r11784 ipython qtconsole --matplotlib=inline
MinRK
code updates per review of PR #454
r4021
MinRK
fix qtconsole description...
r4222 as well as saving your session as HTML, and printing the output.
MinRK
code updates per review of PR #454
r4021
"""
Brian Granger
More work on adding examples to help strings.
r4216 examples = _examples
Brian Granger
Command line examples added for non-parallel apps.
r4215
MinRK
add InlineBackend to ConsoleApp class list...
r7291 classes = [IPythonWidget] + IPythonConsoleApp.classes
MinRK
QtConsole now uses newapp
r3971 flags = Dict(flags)
aliases = Dict(aliases)
MinRK
Split swallow_argv into standalone function in lib.kernel...
r5620 frontend_flags = Any(qt_flags)
frontend_aliases = Any(qt_aliases)
MinRK
update Qt to use KernelClient
r10288 kernel_client_class = QtKernelClient
MinRK
qtconsole autorestarts
r10312 kernel_manager_class = QtKernelManager
MinRK
QtConsole now uses newapp
r3971
stylesheet = Unicode('', config=True,
help="path to a custom CSS stylesheet")
Dan Kilman
Expose configuration to start qtconsole maximized and hide the menu bar on startup
r10960 hide_menubar = CBool(False, config=True,
help="Start the console window with the menu bar hidden.")
maximize = CBool(False, config=True,
help="Start the console window maximized.")
MinRK
add confirm_exit option to qtconsole to suppress exit dialog
r3983 plain = CBool(False, config=True,
MinRK
update docs/default config for qtconsole
r3976 help="Use a plaintext widget instead of rich text (plain can't print/save).")
MinRK
QtConsole now uses newapp
r3971
MinRK
remove references to removed pykernel and associated pure flag
r6806 def _plain_changed(self, name, old, new):
kind = 'plain' if new else 'rich'
MinRK
QtConsole now uses newapp
r3971 self.config.ConsoleWidget.kind = kind
MinRK
remove references to removed pykernel and associated pure flag
r6806 if new:
MinRK
QtConsole now uses newapp
r3971 self.widget_factory = IPythonWidget
MinRK
color settings from ipythonqt propagate down to the ZMQInteractiveShell in the Kernel
r3173 else:
MinRK
QtConsole now uses newapp
r3971 self.widget_factory = RichIPythonWidget
# the factory for creating a widget
widget_factory = Any(RichIPythonWidget)
def parse_command_line(self, argv=None):
super(IPythonQtConsoleApp, self).parse_command_line(argv)
MinRK
Split swallow_argv into standalone function in lib.kernel...
r5620 self.build_kernel_argv(argv)
Paul Ivanov
zmqterminal now uses the zmq mixin app
r5604
MinRK
QtConsole now uses newapp
r3971
MinRK
Work on QtConsole Menu...
r5135 def new_frontend_master(self):
""" Create and return new frontend attached to new kernel, launched on localhost.
Matthias BUSSONNIER
fx tab name and already existing kernel before application launch...
r5039 """
MinRK
use self.kernel_manager_class in qtconsoleapp
r5849 kernel_manager = self.kernel_manager_class(
MinRK
update tabbed qtconsole to use connection files
r5073 connection_file=self._new_connection_file(),
MinRK
use `parent=self` throughout IPython...
r11064 parent=self,
MinRK
qtconsole autorestarts
r10312 autorestart=True,
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 )
# start the kernel
MinRK
remove references to removed pykernel and associated pure flag
r6806 kwargs = dict()
Matthias BUSSONNIER
fx tab name and already existing kernel before application launch...
r5039 kwargs['extra_arguments'] = self.kernel_argv
kernel_manager.start_kernel(**kwargs)
MinRK
qtconsole autorestarts
r10312 kernel_manager.client_factory = self.kernel_client_class
kernel_client = kernel_manager.client()
kernel_client.start_channels(shell=True, iopub=True)
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 widget = self.widget_factory(config=self.config,
MinRK
update tabbed qtconsole to use connection files
r5073 local_kernel=True)
MinRK
adjust qtconsole color logic...
r6056 self.init_colors(widget)
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 widget.kernel_manager = kernel_manager
MinRK
fix new_frontend_master...
r10289 widget.kernel_client = kernel_client
MinRK
cleanup some closing logic...
r5138 widget._existing = False
widget._may_close = True
widget._confirm_exit = self.confirm_exit
MinRK
Work on QtConsole Menu...
r5135 return widget
def new_frontend_slave(self, current_widget):
"""Create and return a new frontend attached to an existing kernel.
Parameters
----------
current_widget : IPythonWidget
The IPythonWidget whose kernel this frontend is to share
"""
MinRK
update Qt to use KernelClient
r10288 kernel_client = self.kernel_client_class(
connection_file=current_widget.kernel_client.connection_file,
MinRK
update tabbed qtconsole to use connection files
r5073 config = self.config,
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 )
MinRK
update Qt to use KernelClient
r10288 kernel_client.load_connection_file()
kernel_client.start_channels()
Matthias BUSSONNIER
tab management new/existing kernel....
r5035 widget = self.widget_factory(config=self.config,
MinRK
update tabbed qtconsole to use connection files
r5073 local_kernel=False)
MinRK
adjust qtconsole color logic...
r6056 self.init_colors(widget)
MinRK
cleanup some closing logic...
r5138 widget._existing = True
widget._may_close = False
widget._confirm_exit = False
MinRK
update Qt to use KernelClient
r10288 widget.kernel_client = kernel_client
MinRK
qtconsole autorestarts
r10312 widget.kernel_manager = current_widget.kernel_manager
MinRK
Work on QtConsole Menu...
r5135 return widget
MinRK
QtConsole now uses newapp
r3971
MinRK
qtconsole autorestarts
r10312 def init_qt_app(self):
# separate from qt_elements, because it must run first
self.app = QtGui.QApplication([])
MinRK
QtConsole now uses newapp
r3971 def init_qt_elements(self):
# Create the widget.
Matthias BUSSONNIER
remove all binary trace from Icons, use directly SVG
r5053
base_path = os.path.abspath(os.path.dirname(__file__))
icon_path = os.path.join(base_path, 'resources', 'icon', 'IPythonConsole.svg')
Matthias BUSSONNIER
use svg icon also for dialog box....
r5055 self.app.icon = QtGui.QIcon(icon_path)
QtGui.QApplication.setWindowIcon(self.app.icon)
Matthias BUSSONNIER
Add icon to qtconsole app...
r5028
MinRK
fix `--existing` with non-localhost IP...
r12110 ip = self.ip
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591 local_kernel = (not self.existing) or is_local_ip(ip)
MinRK
QtConsole now uses newapp
r3971 self.widget = self.widget_factory(config=self.config,
local_kernel=local_kernel)
MinRK
adjust qtconsole color logic...
r6056 self.init_colors(self.widget)
MinRK
cleanup some closing logic...
r5138 self.widget._existing = self.existing
self.widget._may_close = not self.existing
self.widget._confirm_exit = self.confirm_exit
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038
MinRK
QtConsole now uses newapp
r3971 self.widget.kernel_manager = self.kernel_manager
MinRK
update Qt to use KernelClient
r10288 self.widget.kernel_client = self.kernel_client
MinRK
cleanup some closing logic...
r5138 self.window = MainWindow(self.app,
MinRK
Work on QtConsole Menu...
r5135 confirm_exit=self.confirm_exit,
new_frontend_factory=self.new_frontend_master,
slave_frontend_factory=self.new_frontend_slave,
)
Matthias BUSSONNIER
Handle all the case of tab closing and clean the code
r5038 self.window.log = self.log
Matthias BUSSONNIER
decamelcasify: a few more
r5051 self.window.add_tab_with_frontend(self.widget)
Matthias BUSSONNIER
a few more deCamelCasification
r5052 self.window.init_menu_bar()
Matthias BUSSONNIER
triger menu update when kernel started...
r5393
Dan Kilman
Expose configuration to start qtconsole maximized and hide the menu bar on startup
r10960 # Ignore on OSX, where there is always a menu bar
if sys.platform != 'darwin' and self.hide_menubar:
self.window.menuBar().setVisible(False)
MinRK
remove references to removed pykernel and associated pure flag
r6806 self.window.setWindowTitle('IPython')
MinRK
QtConsole now uses newapp
r3971
MinRK
adjust qtconsole color logic...
r6056 def init_colors(self, widget):
MinRK
QtConsole now uses newapp
r3971 """Configure the coloring of the widget"""
# Note: This will be dramatically simplified when colors
# are removed from the backend.
# parse the colors arg down to current known labels
try:
colors = self.config.ZMQInteractiveShell.colors
except AttributeError:
colors = None
try:
MinRK
fix typo preventing `ipython qtconsole --style` from having effect
r5127 style = self.config.IPythonWidget.syntax_style
MinRK
QtConsole now uses newapp
r3971 except AttributeError:
style = None
MinRK
adjust qtconsole color logic...
r6056 try:
sheet = self.config.IPythonWidget.style_sheet
except AttributeError:
sheet = None
MinRK
QtConsole now uses newapp
r3971
# find the value for colors:
if colors:
colors=colors.lower()
if colors in ('lightbg', 'light'):
colors='lightbg'
elif colors in ('dark', 'linux'):
colors='linux'
else:
colors='nocolor'
elif style:
if style=='bw':
colors='nocolor'
elif styles.dark_style(style):
colors='linux'
else:
colors='lightbg'
MinRK
color settings from ipythonqt propagate down to the ZMQInteractiveShell in the Kernel
r3173 else:
MinRK
QtConsole now uses newapp
r3971 colors=None
MinRK
adjust qtconsole color logic...
r6056 # Configure the style
MinRK
QtConsole now uses newapp
r3971 if style:
widget.style_sheet = styles.sheet_from_template(style, colors)
widget.syntax_style = style
MinRK
exposed pygments styles as ipythonqt options
r3170 widget._syntax_style_changed()
widget._style_sheet_changed()
MinRK
added --colors flag to ipythonqt
r3171 elif colors:
MinRK
adjust qtconsole color logic...
r6056 # use a default dark/light/bw style
MinRK
added --colors flag to ipythonqt
r3171 widget.set_default_style(colors=colors)
MinRK
exposed pygments styles as ipythonqt options
r3170
MinRK
QtConsole now uses newapp
r3971 if self.stylesheet:
MinRK
adjust qtconsole color logic...
r6056 # we got an explicit stylesheet
MinRK
QtConsole now uses newapp
r3971 if os.path.isfile(self.stylesheet):
with open(self.stylesheet) as f:
MinRK
exposed pygments styles as ipythonqt options
r3170 sheet = f.read()
else:
MinRK
adjust qtconsole color logic...
r6056 raise IOError("Stylesheet %r not found." % self.stylesheet)
if sheet:
widget.style_sheet = sheet
widget._style_sheet_changed()
MinRK
QtConsole now uses newapp
r3971
MinRK
improve cleanup of connection files...
r5609 def init_signal(self):
"""allow clean shutdown on sigint"""
signal.signal(signal.SIGINT, lambda sig, frame: self.exit(-2))
# need a timer, so that QApplication doesn't block until a real
# Qt event fires (can require mouse movement)
# timer trick from http://stackoverflow.com/q/4938723/938949
timer = QtCore.QTimer()
# Let the interpreter run each 200 ms:
timer.timeout.connect(lambda: None)
timer.start(200)
# hold onto ref, so the timer doesn't get cleaned up
self._sigint_timer = timer
MinRK
catch_config -> catch_config_error
r5214 @catch_config_error
MinRK
QtConsole now uses newapp
r3971 def initialize(self, argv=None):
MinRK
qtconsole autorestarts
r10312 self.init_qt_app()
MinRK
QtConsole now uses newapp
r3971 super(IPythonQtConsoleApp, self).initialize(argv)
MinRK
rename IPythonMixinConsoleApp to IPythonConsoleApp...
r5618 IPythonConsoleApp.initialize(self,argv)
MinRK
QtConsole now uses newapp
r3971 self.init_qt_elements()
MinRK
improve cleanup of connection files...
r5609 self.init_signal()
MinRK
QtConsole now uses newapp
r3971
def start(self):
# draw the window
Dan Kilman
Expose configuration to start qtconsole maximized and hide the menu bar on startup
r10960 if self.maximize:
self.window.showMaximized()
else:
self.window.show()
Matthias BUSSONNIER
put qtconsole forground when launching
r5712 self.window.raise_()
MinRK
exposed pygments styles as ipythonqt options
r3170
MinRK
QtConsole now uses newapp
r3971 # Start the application main loop.
self.app.exec_()
epatters
* Tab completion now uses the correct cursor position....
r2841
MinRK
QtConsole now uses newapp
r3971 #-----------------------------------------------------------------------------
# Main entry point
#-----------------------------------------------------------------------------
def main():
app = IPythonQtConsoleApp()
app.initialize()
app.start()
epatters
* The SVG payload matplotlib backend now works....
r2758
if __name__ == '__main__':
main()