def __init__(self, main_window): """ desc: Constructor. arguments: main_window: The main window object. """ super(ipython_console, self).__init__(main_window) kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() self.kernel = kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.banner1 = '' kernel_client = kernel_manager.client() kernel_client.start_channels() self.control = RichIPythonWidget() self.control.banner = self.banner() self.control.kernel_manager = kernel_manager self.control.kernel_client = kernel_client self.verticalLayout = QtGui.QVBoxLayout(self) self.verticalLayout.setContentsMargins(0,0,0,0) self.setLayout(self.verticalLayout) self.verticalLayout.addWidget(self.control)
def main(): """Start kernel manager and client, create window, run app event loop""" app = guisupport.get_app_qt4() if INPROCESS: from IPython.qt.inprocess import QtInProcessKernelManager km = QtInProcessKernelManager() else: from IPython.qt.manager import QtKernelManager km = QtKernelManager() km.start_kernel() km.kernel.gui = 'qt4' kc = km.client() kc.start_channels() widget = RichIPythonWidget() widget.kernel_manager = km widget.kernel_client = kc if CLEANSHUTDOWN: # slow exit on CTRL+D def stop(): kc.stop_channels() km.shutdown_kernel() app.exit() widget.exit_requested.connect(stop) else: # fast exit on CTRL+D widget.exit_requested.connect(app.quit) widget.show() guisupport.start_event_loop_qt4(app)
def __init__(self, *args, **kw): super(MantidIPythonWidget, self).__init__(*args, **kw) # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' # Figure out the full path to the mantidplotrc.py file and then %run it from os import path mantidplotpath = path.split(path.dirname(__file__))[0] # It's the directory above this one mantidplotrc = path.join(mantidplotpath, 'mantidplotrc.py') shell = kernel.shell shell.run_line_magic('run',mantidplotrc) # These 3 lines replace the run_code method of IPython's InteractiveShell class (of which the # shell variable is a derived instance) with our method defined above. The original method # is renamed so that we can call it from within the our_run_code method. f = shell.run_code shell.run_code = types.MethodType(our_run_code, shell) shell.ipython_run_code = f kernel_client = kernel_manager.client() kernel_client.start_channels() self.kernel_manager = kernel_manager self.kernel_client = kernel_client
def __init__(self, *args, **kw): super(MantidIPythonWidget, self).__init__(*args, **kw) # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' # Figure out the full path to the mantidplotrc.py file and then %run it from os import path mantidplotpath = path.split( path.dirname(__file__))[0] # It's the directory above this one mantidplotrc = path.join(mantidplotpath, 'mantidplotrc.py') shell = kernel.shell shell.run_line_magic('run', mantidplotrc) # These 3 lines replace the run_code method of IPython's InteractiveShell class (of which the # shell variable is a derived instance) with our method defined above. The original method # is renamed so that we can call it from within the our_run_code method. f = shell.run_code shell.run_code = types.MethodType(our_run_code, shell) shell.ipython_run_code = f kernel_client = kernel_manager.client() kernel_client.start_channels() self.kernel_manager = kernel_manager self.kernel_client = kernel_client
def __init__(self, parent): from logging import getLogger, CRITICAL logger=getLogger() silenced=None for handler in logger.handlers: if handler.__class__.__name__=='QtHandler': silenced=handler old_level=silenced.level silenced.setLevel(CRITICAL+1) break RichIPythonWidget.__init__(self) self._parent=parent self.buffer_size=10000 # increase buffer size to show longer outputs self.set_default_style(colors='linux') if IPython.__version__<'1.0': kernelapp=IPythonLocalKernelApp.instance() kernelapp.initialize() self.connect_kernel(connection_file=kernelapp.get_connection_file()) else: kernel_manager=QtInProcessKernelManager(config=self.config, gui='qt4') kernel_manager.start_kernel() self.kernel_manager=kernel_manager self.kernel_client=kernel_manager.client() self.kernel_client.start_channels() ip=get_ipython() # console process exceptions (IPython controlled) ip.set_custom_exc((Exception,), ip_excepthook_overwrite) self.namespace=ip.user_ns self.namespace['IP']=self self.namespace['app']=QtGui.QApplication.instance() self.namespace['gui']=parent self.namespace['plot']=self._plot if silenced: silenced.setLevel(old_level)
def show_ipython_console(): # from https://github.com/ipython/ipython/blob/1.x/examples/inprocess/embedded_qtconsole.py # this might be able to be a dockable panel at some point in the future. # it should also only allow one window open at a time - I think it steals stdout at start # and opening a new window stops output working on the old one! app = guisupport.get_app_qt4() # Create an in-process kernel # >>> print_process_id() # will print the same process ID as the main process kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() app.exit() control = RichIPythonWidget() control.kernel_manager = kernel_manager control.kernel_client = kernel_client control.exit_requested.connect(stop) control.show() guisupport.start_event_loop_qt4(app)
def initialize(self): # Init your plugin self.misc_s = self.locator.get_service('misc') explorer_container = self.locator.get_service('explorer') tree = explorer_container.get_tree_projects() kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() self.ipython_console = RichIPythonWidget() self.ipython_console.kernel_manager = kernel_manager self.ipython_console.kernel_client = kernel_client self.ipython_console.exit_requested.connect(stop) self.ipython_console.show() self.misc_s.add_widget(self.ipython_console, IMAGES["console"], "IPython console") addp = SIGNAL("addProjectToConsole(QString)") delp = SIGNAL("removeProjectFromConsole(QString)") self.connect(tree, addp, self._add_project) self.connect(tree, delp, self._del_project)
def in_process_console(console_class=RichIPythonWidget, **kwargs): """Create a console widget, connected to an in-process Kernel This only works on IPython v 0.13 and above Parameters ---------- console_class : The class of the console widget to create kwargs : Extra variables to put into the namespace """ km = QtInProcessKernelManager() km.start_kernel() kernel = km.kernel kernel.gui = 'qt4' client = km.client() client.start_channels() control = console_class() control.kernel_manager = km control.kernel_client = client control.shell = kernel.shell control.shell.user_ns.update(**kwargs) return control
def main(): #LETS ALSO DO SOME IPYTHOPN PARRALLEL STUFF global splicer app = guisupport.get_app_qt4() from LZM100 import splicer # Create an in-process kernel # >>> print_process_id() # will print the same process ID as the main process kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel.shell.push({'splicer': splicer}) kernel_client = kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() app.exit() control = RichIPythonWidget() control.kernel_manager = kernel_manager control.kernel_client = kernel_client control.exit_requested.connect(stop) control.show() #app = QtGui.QApplication(sys.argv) #ex = Example() b = TaperDesign(Taper()) sys.exit(app.exec_())
def main(): # Print the ID of the main process print_process_id() app = guisupport.get_app_qt4() # Create an in-process kernel # >>> print_process_id() # will print the same process ID as the main process kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel.shell.push({'foo': 43, 'print_process_id': print_process_id}) kernel_client = kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() app.exit() control = RichIPythonWidget() control.kernel_manager = kernel_manager control.kernel_client = kernel_client control.exit_requested.connect(stop) control.show() guisupport.start_event_loop_qt4(app)
def __init__(self): QMainWindow.__init__(self) self.hsplit = QSplitter() self.setCentralWidget(self.hsplit) kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() self.kernel = kernel_manager.kernel self.kernel.gui = 'qt' self.control = RichIPythonWidget(gui_completion="droplist") self.kernel.shell.push({'snipdom': self}) kernel_client = kernel_manager.client() kernel_client.start_channels() self.control.kernel_manager = kernel_manager self.control.kernel_client = kernel_client self.vsplit = QSplitter() self.vsplit.setOrientation(Qt.Vertical) self.vsplit.addWidget(self.control) self.hsplit.addWidget(self.vsplit) self.sendButton = QPushButton("send") #self.sendButton.clicked.connect(self.sendcode) self.vsplit.addWidget(self.sendButton) self.bridge = Js2Py() self.bridge.sent.connect(self.codeFromJs)
class IPythonView(QtGui.QWidget): def __init__(self, parent=None, getfocus=None): super(IPythonView, self).__init__(parent) # Create an in-process kernel self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.shell = self.kernel.shell self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.control = RichIPythonWidget() self.control.set_default_style(colors='linux') self.control.kernel_manager = self.kernel_manager self.control.kernel_client = self.kernel_client self.control.exit_requested.connect(self.stop) # Enable Pylab mode. self.shell.enable_pylab() self.shell.automagic = True # Add some variables in the namespace. self.push(galry=galry) box = QtGui.QVBoxLayout() box.addWidget(self.control) box.setContentsMargins(0, 0, 0, 0) box.setSpacing(0) self.setLayout(box) def stop(self, *args): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() # Public methods. # --------------- def set_data(self, **kwargs): self.push(**kwargs) def push(self, **kwargs): """Inject variables in the interactive namespace.""" self.shell.push(kwargs) def run_file(self, file): """Execute a Python file in the interactive namespace.""" self.shell.safe_execfile(file, self.shell.user_global_ns) def run_cell(self, *args, **kwargs): """Execute a cell.""" self.shell.run_cell(*args, **kwargs)
def __init__(self, interpreter=None, message="", log="", parent=None): """ :param interpreter : InteractiveInterpreter in which the code will be executed :param message: welcome message string :param parent: specifies the parent widget. If no parent widget has been specified, it is possible to exit the interpreter by Ctrl-D. """ if interpreter is None: from openalea.core.service.ipython import interpreter interpreter = interpreter() # Set interpreter self.interpreter = interpreter self.interpreter.widget = self # Multiple Stream Redirection GraphicalStreamRedirection.__init__(self) # Compatibility with visualea self.runsource = self.interpreter.run_cell self.runcode = self.interpreter.runcode self.loadcode = self.interpreter.loadcode # Write welcome message self.write(message) # Set kernel manager try: from IPython.qt.inprocess import QtInProcessKernelManager except ImportError: import warnings message = "You are using a deprecated version of IPython (please update)." warnings.warn(message) # DEPRECATED ! from IPython.frontend.qt.inprocess_kernelmanager import QtInProcessKernelManager km = QtInProcessKernelManager(kernel=self.interpreter) km.start_channels() self.interpreter.frontends.append(km) self.kernel_manager = km else: km = QtInProcessKernelManager() km.kernel = self.interpreter km.kernel.gui = "qt4" kernel_client = km.client() kernel_client.start_channels() self.kernel_manager = km self.kernel_client = kernel_client
class EmbedIPython(RichIPythonWidget): def __init__(self, **kwarg): super(RichIPythonWidget, self).__init__() self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push(kwarg) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels()
class EmbedIPython(RichIPythonWidget): def __init__(self, **kwarg): super(RichIPythonWidget, self).__init__() self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = "qt4" self.kernel.shell.push(kwarg) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels()
def _setup_kernel(self): """ Setup the kernel for the widget. """ kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel_client = kernel_manager.client() kernel_client.start_channels() ipy_widget = self.ipy_widget ipy_widget.kernel_manager = kernel_manager ipy_widget.kernel_client = kernel_client
def __init__(self, interpreter=None, message="", log='', parent=None): """ :param interpreter : InteractiveInterpreter in which the code will be executed :param message: welcome message string :param parent: specifies the parent widget. If no parent widget has been specified, it is possible to exit the interpreter by Ctrl-D. """ if interpreter is None: from openalea.core.service.ipython import interpreter interpreter = interpreter() # Set interpreter self.interpreter = interpreter self.interpreter.widget = self # Multiple Stream Redirection GraphicalStreamRedirection.__init__(self) # Compatibility with visualea self.runsource = self.interpreter.run_cell self.runcode = self.interpreter.runcode self.loadcode = self.interpreter.loadcode # Write welcome message self.write(message) # Set kernel manager try: from IPython.qt.inprocess import QtInProcessKernelManager except ImportError: import warnings message = "You are using a deprecated version of IPython (please update)." warnings.warn(message) # DEPRECATED ! from IPython.frontend.qt.inprocess_kernelmanager import QtInProcessKernelManager km = QtInProcessKernelManager(kernel=self.interpreter) km.start_channels() self.interpreter.frontends.append(km) self.kernel_manager = km else: km = QtInProcessKernelManager() km.kernel = self.interpreter km.kernel.gui = 'qt4' kernel_client = km.client() kernel_client.start_channels() self.kernel_manager = km self.kernel_client = kernel_client
def showEvent(self, e): if not self._initialized: _logger().info('initializing shell') kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel_client = kernel_manager.client() kernel_client.start_channels() self.kernel_manager = kernel_manager self.kernel_client = kernel_client self._initialized = True self.apply_preferences() _logger().info('shell initialized') super(IPythonConsole, self).showEvent(e)
class IPythonWidget(RichIPythonWidget): def __init__(self, parent=None, config=None): super(IPythonWidget, self).__init__(config=config, parent=parent) self.kernel_manager = QtInProcessKernelManager(config=config) self.kernel_manager.start_kernel() self.kernel_manager.kernel.gui = 'qt4' self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.shell = self.kernel_manager.kernel.shell self.user_ns = self.kernel_manager.kernel.shell.user_ns def keyPressEvent(self, e): if e.key() == QtCore.Qt.Key_F2: print "f2"
def __init__( self, parent ): super(self.__class__, self).__init__(parent) # Create an in-process kernel kernel = InProcessKernel(gui='qt4') kernel_manager = QtInProcessKernelManager(kernel=kernel) kernel_manager.start_kernel() kernel_client = kernel_manager.client() kernel_client.start_channels() self.kernel_manager = kernel_manager self.kernel_client = kernel_client self.kernel = kernel self.exit_requested.connect(self._stop) self.show()
def _load_ipython(self): # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel_manager.kernel.gui = "qt4" kernel_manager.kernel.shell.enable_pylab(gui="inline") kernel_client = kernel_manager.client() kernel_client.start_channels() control = RichIPythonWidget() self.ipythonDockWidget.setWidget(control) control.kernel_manager = kernel_manager control.kernel_client = kernel_client control.exit_requested.connect(kernel_client.stop_channels) control.exit_requested.connect(kernel_manager.shutdown_kernel) class IPythonNamespaceUpdater(QtCore.QObject): shell = kernel_manager.kernel.shell def eventFilter(self, target, e): if e.type() == QtCore.QEvent.Enter: self.shell.push(globals()) return False control.installEventFilter(IPythonNamespaceUpdater(self)) class Debug(object): def __init__(self, shell): self.shell = shell def __call__(self): import inspect frame = inspect.currentframe() try: temp = frame.f_back.f_globals temp.update(frame.f_back.f_locals) finally: del frame self.shell.run_line_magic("reset", "-f -s") self.shell.push(temp) # now monkeypatch hexrd.debug to use the qt console: hexrd.debug = Debug(kernel_manager.kernel.shell)
def terminal_widget(**kwargs): # Create an in-process kernel # >>> print_process_id() # will print the same process ID as the main process kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel.shell.push(kwargs) kernel_client = kernel_manager.client() kernel_client.start_channels() control = RichIPythonWidget() control.kernel_manager = kernel_manager control.kernel_client = kernel_client return control
def _load_ipython(self): # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel_manager.kernel.gui = 'qt4' kernel_manager.kernel.shell.enable_pylab(gui='inline') kernel_client = kernel_manager.client() kernel_client.start_channels() control = RichIPythonWidget() self.ipythonDockWidget.setWidget(control) control.kernel_manager = kernel_manager control.kernel_client = kernel_client control.exit_requested.connect(kernel_client.stop_channels) control.exit_requested.connect(kernel_manager.shutdown_kernel) class IPythonNamespaceUpdater(QtCore.QObject): shell = kernel_manager.kernel.shell def eventFilter(self, target, e): if e.type() == QtCore.QEvent.Enter: self.shell.push(globals()) return False control.installEventFilter(IPythonNamespaceUpdater(self)) class Debug(object): def __init__(self, shell): self.shell = shell def __call__(self): import inspect frame = inspect.currentframe() try: temp = frame.f_back.f_globals temp.update(frame.f_back.f_locals) finally: del frame self.shell.run_line_magic('reset', '-f -s') self.shell.push(temp) # now monkeypatch hexrd.debug to use the qt console: hexrd.debug = Debug(kernel_manager.kernel.shell)
def __init__(self, partent): kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt' kernel_client = kernel_manager.client() kernel_client.start_channels() QtGui.QWidget.__init__(self) displayname = QtGui.QLabel('iPython Terminal Widget') mainlayout = QtGui.QGridLayout(self) # console=IPythonWidget(self) console = RichIPythonWidget(self) console.kernel_manager = kernel_manager console.kernel_client = kernel_client console.exit_requested.connect(self.stop) mainlayout.addWidget(console, 0, 0)
def __init__(self,partent): kernel_manager=QtInProcessKernelManager() kernel_manager.start_kernel() kernel=kernel_manager.kernel kernel.gui ='qt' kernel_client=kernel_manager.client() kernel_client.start_channels() QtGui.QWidget.__init__(self) displayname=QtGui.QLabel('iPython Terminal Widget') mainlayout=QtGui.QGridLayout(self) # console=IPythonWidget(self) console=RichIPythonWidget(self) console.kernel_manager=kernel_manager console.kernel_client=kernel_client console.exit_requested.connect(self.stop) mainlayout.addWidget(console,0,0)
def __init__(self, mbus): super(Main, self).__init__() self.mbus = mbus layout = QtWidgets.QVBoxLayout(self) # ipython console for scripting kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel_client = kernel_manager.client() kernel_client.start_channels() self._console = IPythonWidget(font_size=9) self._console.kernel_manager = kernel_manager self._console.kernel_client = kernel_client layout.addWidget(self._console) self.setWindowTitle("Messagebus Ipython Console.") # push useful imports to console. self.push(np=np, mbus=mbus, subscribe=self.subscribe)
def initialize(self): kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = "qt4" kernel_client = kernel_manager.client() kernel_client.start_channels() app = guisupport.get_app_qt4() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() app.exit() self.kernel = kernel self.kernel_manager = kernel_manager self.kernel_client = kernel_client self.exit_requested.connect(stop)
def initialize(self): kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() app = guisupport.get_app_qt4() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() app.exit() self.kernel = kernel self.kernel_manager = kernel_manager self.kernel_client = kernel_client self.exit_requested.connect(stop)
class IPythonConsole(RichIPythonWidget): def __init__(self, namespace = dict(), **kwargs): super(RichIPythonWidget, self).__init__() self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.user_ns = namespace self.kernel.shell.push(kwargs) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.exit_requested.connect(self.exit) def update_namespace(self, **kwargs): self.kernel.shell.push(kwargs) def exit(self, *args): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() sys.exit()
class SilverIPython(RichIPythonWidget): ''' Wraps an IPython kernel and provides IPython widgets for it ''' def __init__(self): RichIPythonWidget.__init__(self) self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push({'window': self, 'kernel': self.kernel}) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.kernel_client.execute('%pylab inline') self.exit_requested.connect(self.exit_requested_func) def send_execute(self, *args, **kwargs): self.kernel_client.execute(*args, **kwargs) def exit_requested_func(self): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() qt_app.exit()
class SilverIPython(RichIPythonWidget): ''' Wraps an IPython kernel and provides IPython widgets for it ''' def __init__(self): RichIPythonWidget.__init__(self) self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push({'window': self, 'kernel': self.kernel}) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.kernel_client.execute('%pylab inline') self.exit_requested.connect(self.exit_requested_func) def send_execute(self, *args,**kwargs): self.kernel_client.execute( *args,**kwargs ) def exit_requested_func(self): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() qt_app.exit()
class IPythonConnection(): def __init__(self): self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() # Suppress debug messages self.kernel.log.setLevel(logging.WARNING) def get_widget(self, droplist_completion=True): completion = 'droplist' if droplist_completion else 'plain' widget = RichIPythonWidget(gui_completion=completion) widget.kernel_manager = self.kernel_manager widget.kernel_client = self.kernel_client return widget def push(self, d): self.kernel.shell.push(d)
def main(): """Start kernel manager and client, create window, run app event loop, auto execute some code in user namespace. A minimalist example is shown in qt_ip_test.py. This is gleaned from ipython.examples.inprocess.embedded_qtconsole and ipython.IPython.qt.console.qtconsoleapp.new_frontend_master()""" app = guisupport.get_app_qt4() if INPROCESS: from IPython.qt.inprocess import QtInProcessKernelManager km = QtInProcessKernelManager() else: from IPython.qt.manager import QtKernelManager km = QtKernelManager() km.start_kernel() km.kernel.gui = 'qt4' kc = km.client() kc.start_channels() neuropywindow = NeuropyWindow() ipw = neuropywindow.ipw config_ipw(ipw) ipw.exit_requested.connect(app.quit) ipw.kernel_manager = km ipw.kernel_client = kc neuropywindow.show() # execute some code directly, note the output appears at the system command line: #kernel.shell.run_cell('print "x=%r, y=%r, z=%r" % (x,y,z)') # execute some code through the frontend (once the event loop is running). # The output appears in the ipw. __future__ import in startup.py doesn't seem to work, # execute directly: do_later(ipw.execute, "from __future__ import division", hidden=True) do_later(ipw.execute, "from __future__ import print_function", hidden=True) do_later(ipw.execute_file, 'startup.py', hidden=True) do_later(ipw.execute_file, 'globals.py', hidden=True) guisupport.start_event_loop_qt4(app)
class IPythonInProcess(object): def __init__(self,common,customBanner=None): if customBanner!=None: self.banner=customBanner self.common = common self.kernel_manager = None self.kernel = None self.control = None self.kernel_client = None self.init_qtconsole() def init_qtconsole(self): self.main() def print_process_id(self): print('Process ID is:', os.getpid()) def main(self): # Print the ID of the main process #self.print_process_id() #app = guisupport.get_app_qt4() # Create an in-process kernel # >>> print_process_id() # will print the same process ID as the main process self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push(self.common.__dict__) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() def stop(): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() #app.exit() self.control = RichIPythonWidget(banner = self.banner) self.control.kernel_manager = self.kernel_manager self.control.kernel_client = self.kernel_client self.control.exit_requested.connect(stop) #start widget with certain inputs: #import pylab, which includes all numpy; import pandas as pd #second argument is whether the execution is hidden e.g. whether a line is used #I have turned on hide. self.control._execute('import pylab as pl; import pandas as pd',True) def SHOW(self): self.control.show() #guisupport.start_event_loop_qt4(app) def pushVariables(self,variableDict): """ Given a dictionary containing name / value pairs, push those variables to the IPython console widget """ self.kernel_manager.kernel.shell.push(variableDict) def clearTerminal(self): """ Clears the terminal """ self._control.clear() def printText(self,text): """ Prints some plain text to the console """ self._append_plain_text(text) def executeCommand(self,command): """ Execute a command in the frame of the console widget """ self.control._execute(command,False)
class BaseApp(QtCore.QObject): def __init__(self, argv=[]): QtCore.QObject.__init__(self) self.log = get_logger_from_class(self) self.this_dir, self.this_filename = os.path.split(__file__) self.qtapp = QtWidgets.QApplication.instance() if not self.qtapp: self.qtapp = QtWidgets.QApplication(argv) self.settings = LQCollection() # auto creation of console widget self.setup_console_widget() # FIXME Breaks things for microscopes, but necessary for stand alone apps! #if hasattr(self, "setup"): # self.setup() self.setup_logging() if not hasattr(self, 'name'): self.name = "ScopeFoundry" self.qtapp.setApplicationName(self.name) def exec_(self): return self.qtapp.exec_() def setup_console_widget(self, kernel=None): """ Create and return console QWidget. If Jupyter / IPython is installed this widget will be a full-featured IPython console. If Jupyter is unavailable it will fallback to a pyqtgraph.console.ConsoleWidget. If the app is started in an Jupyter notebook, the console will be connected to the notebook's IPython kernel. the returned console_widget will also be accessible as self.console_widget In order to see the console widget, remember to insert it into an existing window or call self.console_widget.show() to create a new window """ if CONSOLE_TYPE == 'pyqtgraph.console': self.console_widget = pyqtgraph.console.ConsoleWidget( namespace={ 'app': self, 'pg': pg, 'np': np }, text="ScopeFoundry Console") elif CONSOLE_TYPE == 'qtconsole': if kernel == None: try: # try to find an existing kernel #https://github.com/jupyter/notebook/blob/master/docs/source/examples/Notebook/Connecting%20with%20the%20Qt%20Console.ipynb import ipykernel as kernel conn_file = kernel.get_connection_file() import qtconsole.qtconsoleapp self.qtconsole_app = qtconsole.qtconsoleapp.JupyterQtConsoleApp( ) self.console_widget = self.qtconsole_app.new_frontend_connection( conn_file) self.console_widget.setWindowTitle( "ScopeFoundry IPython Console") except: # make your own new in-process kernel # https://github.com/ipython/ipython-in-depth/blob/master/examples/Embedding/inprocess_qtconsole.py self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.shell.banner1 += """ ScopeFoundry Console Variables: * np: numpy package * app: the ScopeFoundry App object """ self.kernel.gui = 'qt4' self.kernel.shell.push({'np': np, 'app': self}) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() #self.console_widget = RichIPythonWidget() self.console_widget = RichJupyterWidget() self.console_widget.setWindowTitle( "ScopeFoundry IPython Console") self.console_widget.kernel_manager = self.kernel_manager self.console_widget.kernel_client = self.kernel_client else: import qtconsole.qtconsoleapp self.qtconsole_app = qtconsole.qtconsoleapp.JupyterQtConsoleApp( ) self.console_widget = self.qtconsole_app.new_frontend_connection( kernel.get_connection_file()) self.console_widget.setWindowTitle( "ScopeFoundry IPython Console") else: raise ValueError("CONSOLE_TYPE undefined") return self.console_widget def setup(self): pass def settings_save_ini(self, fname, save_ro=True): """""" config = configparser.ConfigParser() config.optionxform = str config.add_section('app') config.set('app', 'name', self.name) for lqname, lq in self.settings.as_dict().items(): if not lq.ro or save_ro: config.set('app', lqname, lq.ini_string_value()) with open(fname, 'w') as configfile: config.write(configfile) self.log.info("ini settings saved to {} {}".format( fname, config.optionxform)) def settings_load_ini(self, fname): self.log.info("ini settings loading from " + fname) config = configparser.ConfigParser() config.optionxform = str config.read(fname) if 'app' in config.sections(): for lqname, new_val in config.items('app'): #print(lqname) lq = self.settings.as_dict().get(lqname) if lq: if lq.dtype == bool: new_val = str2bool(new_val) lq.update_value(new_val) def settings_save_ini_ask(self, dir=None, save_ro=True): """Opens a Save dialogue asking the user to select a save destination and give the save file a filename. Saves settings to an .ini file.""" # TODO add default directory, etc fname, _ = QtWidgets.QFileDialog.getSaveFileName( self.ui, caption=u'Save Settings', dir=u"", filter=u"Settings (*.ini)") #print(repr(fname)) if fname: self.settings_save_ini(fname, save_ro=save_ro) return fname def settings_load_ini_ask(self, dir=None): """Opens a Load dialogue asking the user which .ini file to load into our app settings. Loads settings from an .ini file.""" # TODO add default directory, etc fname, _ = QtWidgets.QFileDialog.getOpenFileName( None, "Settings (*.ini)") #print(repr(fname)) if fname: self.settings_load_ini(fname) return fname def setup_logging(self): logging.basicConfig( level=logging.WARN) #, filename='example.log', stream=sys.stdout) logging.getLogger('traitlets').setLevel(logging.WARN) logging.getLogger('ipykernel.inprocess').setLevel(logging.WARN) logging.getLogger('LoggedQuantity').setLevel(logging.WARN) logging.getLogger('PyQt5').setLevel(logging.WARN) logger = logging.getLogger('FoundryDataBrowser') self.logging_widget = QtWidgets.QWidget() self.logging_widget.setWindowTitle("Log") self.logging_widget.setLayout(QtWidgets.QVBoxLayout()) self.logging_widget.search_lineEdit = QtWidgets.QLineEdit() self.logging_widget.log_textEdit = QtWidgets.QTextEdit("") self.logging_widget.layout().addWidget( self.logging_widget.search_lineEdit) self.logging_widget.layout().addWidget( self.logging_widget.log_textEdit) self.logging_widget.log_textEdit.document().setDefaultStyleSheet( "body{font-family: Courier;}") self.logging_widget_handler = LoggingQTextEditHandler( self.logging_widget.log_textEdit, level=logging.DEBUG) logging.getLogger().addHandler(self.logging_widget_handler)
def procsteppython_do_run(stepglobals, runfunc, argkw, ipythonmodelist, action, scripthref, pycode_text, pycode_lineno): if not ipythonmodelist[0]: resultdict = runfunc(**argkw) return resultdict else: # ipython mode # in-process kernel, a-la https://raw.githubusercontent.com/ipython/ipython/master/examples/Embedding/inprocess_qtconsole.py ## Set PyQt4 API version to 2 and import it -- required for ipython compatibility #import sip #sip.setapi('QVariant', 2) #sip.setapi('QString', 2) #sip.setapi('QDateTime', 2) #sip.setapi('QDate', 2) #sip.setapi('QTextStream', 2) #sip.setapi('QTime', 2) #sip.setapi('QUrl', 2) #from PyQt4 import QtGui # force IPython to use PyQt4 by importing it first # RHEL6 compatibility -- if running under Python 2.6, just import IPython, get PyQt4 if sys.version_info < (2, 7): from IPython.qt.console.rich_ipython_widget import RichIPythonWidget from IPython.qt.inprocess import QtInProcessKernelManager pass else: # Under more recent OS's: Make matplotlib use PySide # http://stackoverflow.com/questions/6723527/getting-pyside-to-work-with-matplotlib import matplotlib matplotlib.use('Qt4Agg') matplotlib.rcParams['backend.qt4'] = 'PySide' pass import IPython from IPython.core.interactiveshell import DummyMod if LooseVersion(IPython.__version__) >= LooseVersion('4.0.0'): # Recent Jupyter/ipython: Import from qtconsole # Force PySide bindings import PySide.QtCore from qtconsole.qt import QtGui from qtconsole.inprocess import QtInProcessKernelManager # Obtain the running QApplication instance app = QtGui.QApplication.instance() if app is None: # Start our own if necessary app = QtGui.QApplication([]) pass pass else: from IPython.qt.inprocess import QtInProcessKernelManager from IPython.lib import guisupport app = guisupport.get_app_qt4() pass kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' #sys.stderr.write("id(stepglobals)=%d" % (id(stepglobals))) # Make ipython use our globals as its global dictionary # ... but first keep a backup stepglobalsbackup = copy.copy(stepglobals) (kernel.user_module, kernel.user_ns) = kernel.shell.prepare_user_module( user_ns=stepglobals) # Should we attempt to run the function here? # (gui, backend) = kernel.shell.enable_matplotlib("qt4") #,import_all=False) # (args.gui, import_all=import_all) (gui, backend, clobbered) = kernel.shell.enable_pylab( "qt4", import_all=False) # (args.gui, import_all=import_all) # kernel.shell.push(stepglobals) # provide globals as variables -- no longer necessary as it's using our namespace already kernel.shell.push(argkw) # provide arguments as variables kernel.shell.push( {"kernel": kernel}, interactive=False) # provide kernel for debugging purposes kernel_client = kernel_manager.client() kernel_client.start_channels() abort_requested_list = [False ] # encapsulated in a list to make it mutable def stop(): control.hide() kernel_client.stop_channels() kernel_manager.shutdown_kernel() app.exit() pass def abort(): # simple exit doesn't work. See http://stackoverflow.com/questions/1527689/exit-from-ipython # too bad this doesn't work right now!!! class Quitter(object): def __repr__(self): sys.exit() pass kernel.shell.push({"quitter": Quitter()}) kernel.shell.ex("quitter") stop() abort_requested_list.pop() abort_requested_list.append(True) pass if pycode_text is None: kernel.shell.write("\n\nExecute %s/%s\n" % (scripthref.getpath(), runfunc.__name__)) pass else: kernel.shell.write( "\n\nExecute %s/%s/%s\n" % (scripthref.getpath(), action, runfunc.__name__)) pass kernel.shell.write("Assign return value to \"ret\" and press Ctrl-D\n") kernel.shell.write("Set cont=True to disable interactive mode\n") # kernel.shell.write("call abort() to exit\n") if LooseVersion(IPython.__version__) >= LooseVersion('4.0.0'): # Recent Jupyter/ipython: Import from qtconsole from qtconsole.rich_jupyter_widget import RichJupyterWidget as RichIPythonWidget pass else: from IPython.qt.console.rich_ipython_widget import RichIPythonWidget pass control = RichIPythonWidget() control.kernel_manager = kernel_manager control.kernel_client = kernel_client control.exit_requested.connect(stop) control.show() #sys.stderr.write("lines=%s\n" % (str(lines))) #sys.stderr.write("lines[0]=%s\n" % (str(lines[0]))) try: if pycode_text is None: (lines, startinglineno) = inspect.getsourcelines(runfunc) assert (lines[0].startswith("def") ) # first line of function is the defining line del lines[0] # remove def line lines.insert(0, "if 1:\n") # allow function to be indented runfunc_syntaxtree = ast.parse( "".join(lines), filename=scripthref.getpath(), mode='exec' ) # BUG: Should set dont_inherit parameter and properly determine which __future__ import flags should be passed # fixup line numbers for syntreenode in ast.walk(runfunc_syntaxtree): if hasattr(syntreenode, "lineno"): syntreenode.lineno += startinglineno - 1 pass pass # runfunc_syntaxtree should consist of the if statement we just added # use _fields attribute to look up fields of an AST element # (e.g. test, body, orelse for IF) # then those fields can be accessed directly assert (len(runfunc_syntaxtree.body) == 1) code_container = runfunc_syntaxtree.body[0] assert (isinstance(code_container, ast.If) ) # code_container is the if statement we just wrote kernel.shell.push( {"runfunc_syntaxtree": runfunc_syntaxtree}, interactive=False ) # provide processed syntax tree for debugging purposes pass else: fullsyntaxtree = ast.parse( pycode_text ) # BUG: Should set dont_inherit parameter and properly determine which __future__ import flags should be passed # fixup line numbers for syntreenode in ast.walk(fullsyntaxtree): if hasattr(syntreenode, "lineno"): syntreenode.lineno += pycode_lineno - 1 pass pass code_container = None for codeelement in fullsyntaxtree.body: if isinstance(codeelement, ast.FunctionDef): if codeelement.name == runfunc.__name__: code_container = codeelement runfunc_syntaxtree = codeelement pass pass pass if code_container is None: raise ValueError( "Couldn't find code for %s for ipython execution" % (runfunc.__name__)) kernel.shell.push( {"fullsyntaxtree": fullsyntaxtree}, interactive=False ) # provide full syntax tree for debugging purposes pass # identify global variables from runfunc_syntaxtree globalvars = set() for treeelem in ast.walk(runfunc_syntaxtree): if isinstance(treeelem, ast.Global): globalvars = globalvars.union(treeelem.names) pass pass kernel.shell.push({"abort": abort}) # provide abort function kernel.shell.push({"cont": False}) # continue defaults to False returnstatement = code_container.body[-1] if isinstance(returnstatement, ast.Return): # last statement is a return statement! # Create assign statement that assigns # the result to ret retassign = ast.Assign(targets=[ ast.Name(id="ret", ctx=ast.Store(), lineno=returnstatement.lineno, col_offset=returnstatement.col_offset) ], value=returnstatement.value, lineno=returnstatement.lineno, col_offset=returnstatement.col_offset) del code_container.body[-1] # remove returnstatement code_container.body.append(retassign) # add assignment pass runfunc_lines = code_container.body kernel.shell.push( { "runfunc_lines": runfunc_lines, "scripthref": scripthref }, interactive=False ) # provide processed syntax tree for debugging purposes # kernel.shell.run_code(compile("kernel.shell.run_ast_nodes(runfunc_lines,scriptpath,interactivity='all')","None","exec")) if LooseVersion(IPython.__version__) >= LooseVersion('4.0.0'): # Recent Jupyter/ipython: Import from qtconsole from qtconsole.inprocess import QtCore pass else: from IPython.qt.inprocess import QtCore pass QTimer = QtCore.QTimer def showret(): control.execute("ret") pass def runcode(): control.execute( "kernel.shell.run_ast_nodes(runfunc_lines,scripthref.getpath(),interactivity='none')" ) # QTimer.singleShot(25,showret) # get callback 25ms into main loop # showret disabled because it prevents you from running the # debugger in post-mortem mode to troubleshoot an exception: # import pdb; pdb.pm() pass QTimer.singleShot(25, runcode) # get callback 25ms into main loop # control.execute("kernel.shell.run_ast_nodes(runfunc_lines,scripthref.getpath(),interactivity='none')") pass except: (exctype, excvalue) = sys.exc_info()[:2] sys.stderr.write( "%s while attempting to prepare URL %s code for interactive execution: %s\n" % (exctype.__name__, scripthref.absurl(), str(excvalue))) traceback.print_exc() raise if LooseVersion(IPython.__version__) >= LooseVersion('4.0.0'): # Recent Jupyter/ipython: Import from qtconsole app.exec_() pass else: # Old ipython guisupport.start_event_loop_qt4(app) pass if abort_requested_list[0]: pass if kernel.shell.ev("cont"): # cont==True -> disable interactive mode ipythonmodelist.pop() ipythonmodelist.append(False) pass try: retval = kernel.shell.ev( "ret") # Assign result dictionary to "ret" variable pass except NameError: # if ret not assigned, return {} retval = {} pass # Performing this execution changed values in stepglobals # but it should have only done that for variables specified # as 'global' in the function. # So: Update our backup of the value of stepglobals, # according to the specified globals, and # replace stepglobals with that updated backup stepglobalsbackup.update( dict([(varname, stepglobals[varname]) for varname in globalvars])) stepglobals.clear() stepglobals.update(stepglobalsbackup) return retval pass
def run(self, dock=False): # Checks if a console is open if self.status is not None: if (dock and self.status == 'docked') or (not dock and self.status == 'windowed'): if self.status == 'windowed': self.control.raise_() self.control.activateWindow() return elif self.status == 'docked': # Close current if self.dock is not None: self.dock.close() else: # Close current self.control.close() try: if QT_VERSION==4: from IPython.qt.console.rich_ipython_widget import RichIPythonWidget else: from qtconsole.rich_ipython_widget import RichIPythonWidget from IPython.qt.inprocess import QtInProcessKernelManager from qgis import core, gui # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt%s' % (QT_VERSION if QT_VERSION != 5 else '') kernel.shell.push({ 'iface': self.iface, 'canvas': self.canvas, 'core' : core, 'gui' : gui, 'propertize': propertize, 'plugin_instance' : self, #'app': app, }) if int(self.get_settings('propertize', DEFAULT_PROPERTIZE)): kernel.shell.ex('propertize(core)') kernel.shell.ex('propertize(gui)') # Import in the current namespace kernel.shell.ex('from PyQt%s.QtCore import *' % QT_VERSION) kernel.shell.ex('from PyQt%s.QtGui import *' % QT_VERSION) kernel.shell.ex('from qgis.core import *') kernel.shell.ex('from qgis.gui import *') kernel_client = kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() # No: this exits QGIS! #app.exit() self.status = None self.control = None self.dock = None # or RichIPythonWidget class myWidget(RichIPythonWidget): def closeEvent(self, event): stop() event.accept() def resizeEvent(self, event): super(myWidget, self).resizeEvent(event) self.console_resize() event.accept() def get_columns(self): try: font_width = QFontMetrics(self.font).width(' ') except TypeError: font_width = 10 return int(self.size().width() / font_width) def console_resize(self): self.width = self.get_columns() class myDock(QDockWidget): def closeEvent(self, event): stop() event.accept() # IPythonWidget.gui_completion : ‘plain’|’droplist’|’ncurses’ # IPythonWidget.height : Integer # IPythonWidget.width : Integer # TODO: settings # myWidget.width = 160 myWidget.gui_completion = 'plain' myWidget.paging = 'none' self.control = myWidget() self.control.kernel_manager = kernel_manager self.control.kernel_client = kernel_client self.control.exit_requested.connect(stop) if not dock: self.status = 'windowed' self.control.show() else: self.status = 'docked' self.dock = myDock() self.dock.setWidget(self.control) self.iface.addDockWidget(Qt.BottomDockWidgetArea, self.dock) # Font size regulation self.set_font() self.control._set_font(self.console_font) def shout(): from IPython.core import usage self.control._control.clear() self.control._reading = False self.control._highlighter.highlighting_on = False try: self.control._append_before_prompt_pos = self.control._get_cursor().position() except Exception as ex: # Can't set attribute .... on mac/win pass if int(self.get_settings('show_help', DEFAULT_SHOW_HELP)): try: banner = usage.default_banner except: try: banner = usage.default_gui_banner except: banner = '' self.control._append_html('<small>%s</small>' % banner.replace('\n', '<br>').strip()) if int(self.get_settings('propertize', DEFAULT_PROPERTIZE)): propertize_text = ("""All returning-something and no-args <code>core</code> and <code>gui</code> <code>Qgs*</code> class members have a <code>p_*</code> equivalent property to ease class introspection with <strong>TAB</strong> completion.""") else: propertize_text = _tr("""Propertize has been disabled, you can re-activate it in the pugin's settings.""") self.control._append_html( _tr("""<br><h3>Welcome to QGIS <a href="https://ipython.org/">IPython</a> Console</h3> You have access to <code>canvas</code>, <code>iface</code>, <code>app</code> (QGIS application) objects and to all <code>qgis</code> and <code>PyQt</code> <code>core</code> and <code>gui</code> modules directly from the shell. %s Don't forget that you have access to all your underlying shell commands too!<br> <em>Enjoy IPyConsole! Another hack by <a href="http://www.itopen.it">ItOpen</a></em></br> """) % propertize_text) def monkey_patch_columnize(control): """As the name suggests... dynamic column number: stock qtconsole doesn't resize its column number on window resize but sticks to 80""" from IPython.qt.console.completion_plain import text old_columnize = text.columnize def new_columnize(items, separator=' ', displaywidth=80): displaywidth = control.get_columns() return old_columnize(items, separator, displaywidth) text.columnize = new_columnize monkey_patch_columnize(self.control) QTimer.singleShot(0, shout) except ImportError as e: error_message = _tr(u'You need to install <b>Jupyter 1.0.0</b> (and then restart QGIS) before running this <b>IPyConsole</b> plugin.<br>IPython can be installed with <code>pip install <code>pip install jupyter==1.0.0 qtconsole</code>. More informations about IPython installation on <a href="https://ipython.org/install.html">https://ipython.org/install.html</a>. Windows users might need to run the commands as admin in the OSGEO Command Shell.<br>The exception message is: %s') % e if HAS_PIP: install_message = _tr(u'<br>Press "Ok" if you would you like to try an automatic installation of the required packages (it may take some time depending on your network connection speed, total size is ~100 MB), press "Cancel" to install manually.' ) dlg = DepsDialog(error_message + install_message) dlg.exec_() else: QMessageBox.information(self.iface.mainWindow(), _tr(u'Error'), error_message)
class NotebookRunner(BaseFrontendMixin, QObject): ''' A runner object that handles running the running of IPython notebook and working responses back into the output notebook. Based off the original runipy code amended to handle in-process running and the IPython FrontendWidget. ''' # Emitted when a user visible 'execute_request' has been submitted to the # kernel from the FrontendWidget. Contains the code to be executed. executing = pyqtSignal(object) # Emitted when a user-visible 'execute_reply' has been received from the # kernel and processed by the FrontendWidget. Contains the response message. executed = pyqtSignal(object) # Emitted when an exit request has been received from the kernel. exit_requested = pyqtSignal(object) # Execute next cell execute_next = pyqtSignal() # Emitted when all cells a notebook have been run notebook_completed = pyqtSignal() notebook_result = pyqtSignal(object) # Emit current cell number progress = pyqtSignal(object) _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos']) _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos']) _ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind']) _local_kernel = False _hidden = False MIME_MAP = { 'image/jpeg': 'jpeg', 'image/png': 'png', 'text/plain': 'text', 'text/html': 'html', 'text/latex': 'latex', 'application/javascript': 'html', 'image/svg+xml': 'svg', } #--------------------------------------------------------------------------- # 'object' interface #--------------------------------------------------------------------------- def __init__(self, *args, **kwargs): super(NotebookRunner, self).__init__(*args, **kwargs) # FrontendWidget protected variables. self._kernel_manager = None self._kernel_client = None self._request_info = {} self._request_info['execute'] = {}; self._callback_dict = {} self._result_queue = [] self._final_msg_id = None self._cell_execute_ids = {} self._is_active = False self._executing = False # Set flag for whether we are connected via localhost. self._local_kernel = kwargs.get('local_kernel', NotebookRunner._local_kernel) self.kernel_manager = KernelManager() self.kernel_manager.start_kernel() self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels(stdin=False, hb=False) def __del__(self): if self.kernel_client: self.kernel_client.stop_channels() if self.kernel_manager: self.kernel_manager.shutdown_kernel() def iter_code_cells(self): ''' Iterate over the notebook cells containing code. ''' for ws in self.nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': yield cell def count_code_cells(self): ''' Return the number of code cells in the notebook ''' for n, cell in enumerate(self.iter_code_cells()): pass return n+1 def run_notebook(self, notebook, varsi, progress_callback=None, result_callback=None): ''' Run all the cells of a notebook in order and update the outputs in-place. ''' self.nb = notebook self.varsi = varsi # Pickle all variables and import to the notebook (depickler) with open(self.varsi['_pathomx_pickle_in'], 'wb') as f: pickle.dump(self.varsi, f, -1) # Highest protocol for speed self._progress_callback = progress_callback self._result_callback = result_callback self._notebook_generator = self.iter_code_cells() self._total_code_cell_number = self.count_code_cells() self._is_active = True self._result_queue = [] # Cache for unhandled messages self._cell_execute_ids = {} self._execute_start = datetime.now() msg_id = self._execute('''%%reset -f from pathomx import pathomx_notebook_start, pathomx_notebook_stop pathomx_notebook_start('%s', vars());''' % (self.varsi['_pathomx_pickle_in']) ) logging.debug("Runing notebook; startup message: %s" % msg_id) for n, cell in enumerate(self.iter_code_cells()): msg_id = self._execute(cell.input) logging.debug('Cell number %d; %s' % ( n, msg_id) ) progress = n / float(self._total_code_cell_number) self._cell_execute_ids[ msg_id ] = (cell, n+1, progress) # Store cell and progress self._final_msg_id = self._execute('''pathomx_notebook_stop('%s', vars());''' % (self.varsi['_pathomx_pickle_out'])) logging.debug("Runing notebook; shutdown message: %s" % self._final_msg_id) def run_notebook_completed(self, error=False, traceback=None): logging.info("Notebook run took %s" % ( datetime.now() - self._execute_start ) ) result = {} if error: result['status'] = -1 result['traceback'] = traceback else: # Apply unhandled results for msg in self._result_queue: self._handle_execute_result(msg) result['status'] = 0 # Return input; temp with open(self.varsi['_pathomx_pickle_out'], 'rb') as f: result['varso'] = pickle.load(f) result['notebook'] = self.nb self._is_active = False self.notebook_completed.emit() self.notebook_result.emit(result) if self._result_callback: self._result_callback(result) def _execute(self, source, hidden=False): """ Execute 'source'. If 'hidden', do not show any output. See parent class :meth:`execute` docstring for full details. """ msg_id = self.kernel_client.execute(source, hidden) self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'user') self._hidden = hidden #if not hidden: # self.executing.emit(source) return msg_id #--------------------------------------------------------------------------- # 'BaseFrontendMixin' abstract interface #--------------------------------------------------------------------------- def _handle_clear_output(self, msg): """Handle clear output messages.""" if not self._hidden and self._is_from_this_session(msg): wait = msg['content'].get('wait', True) if wait: self._pending_clearoutput = True else: self.clear_output() def _handle_execute_reply(self, msg): """ Handles replies for code execution. """ logging.debug("execute: %s", msg.get('content', '')) msg_id = msg['parent_header']['msg_id'] if msg_id == self._final_msg_id: return self.run_notebook_completed() if msg_id not in self._cell_execute_ids: return (self._current_cell, n, pc) = self._cell_execute_ids[msg_id] logging.info("Execute cell %d complete in %s" % (n, datetime.now() - self._execute_start) ) self.progress.emit( pc ) if self._progress_callback: self._progress_callback( pc ) info = self._request_info['execute'].get(msg_id) # unset reading flag, because if execute finished, raw_input can't # still be pending. self._reading = False if info and info.kind == 'user' and not self._hidden: # Make sure that all output from the SUB channel has been processed # before writing a new prompt. self.kernel_client.iopub_channel.flush() # Reset the ANSI style information to prevent bad text in stdout # from messing up our colors. We're not a true terminal so we're # allowed to do this. # if self.ansi_codes: # self._ansi_processor.reset_sgr() content = msg['content'] status = content['status'] if status == 'ok': self._process_execute_ok(msg) self.execute_next.emit() elif status == 'error': self._process_execute_error(msg) elif status == 'aborted': self._process_execute_abort(msg) self.executed.emit(msg) self._request_info['execute'].pop(msg_id) elif info and info.kind == 'silent_exec_callback' and not self._hidden: self._handle_exec_callback(msg) self._request_info['execute'].pop(msg_id) else: super(FrontendWidget, self)._handle_execute_reply(msg) def _process_execute_abort(self, msg): """ Process a reply for an aborted execution request. """ logging.error("ERROR: execution aborted\n") def _process_execute_error(self, msg): """ Process a reply for an execution request that resulted in an error. """ content = msg['content'] # If a SystemExit is passed along, this means exit() was called - also # all the ipython %exit magic syntax of '-k' to be used to keep # the kernel running if content['ename']=='SystemExit': keepkernel = content['evalue']=='-k' or content['evalue']=='True' self._keep_kernel_on_exit = keepkernel self.exit_requested.emit(self) else: traceback = ''.join(content['traceback']) logging.error(traceback) out = NotebookNode(output_type='pyerr') out.ename = content['ename'] out.evalue = content['evalue'] out.traceback = content['traceback'] self._current_cell['outputs'].append(out) self.run_notebook_completed(error=True, traceback=content['traceback']) def _process_execute_ok(self, msg): """ Process a reply for a successful execution request. """ payload = msg['content']['payload'] for item in payload: if not self._process_execute_payload(item): warning = 'Warning: received unknown payload of type %s' print(warning % repr(item['source'])) content = msg['content'] msg_type = msg['msg_type'] # IPython 3.0.0-dev writes pyerr/pyout in the notebook format but uses # error/execute_result in the message spec. This does the translation # needed for tests to pass with IPython 3.0.0-dev notebook3_format_conversions = { 'error': 'pyerr', 'execute_result': 'pyout' } msg_type = notebook3_format_conversions.get(msg_type, msg_type) out = NotebookNode(output_type=msg_type) if 'execution_count' in content: self._current_cell['prompt_number'] = content['execution_count'] out.prompt_number = content['execution_count'] if msg_type in ('status', 'pyin', 'execute_input'): return elif msg_type == 'stream': out.stream = content['name'] out.text = content['data'] elif msg_type in ('display_data', 'pyout'): # Is this handled in _handle_execute_result? for mime, data in content['data'].items(): try: attr = self.MIME_MAP[mime] except KeyError: raise NotImplementedError('unhandled mime type: %s' % mime) setattr(out, attr, data) return elif msg_type == 'pyerr': # Is this handled in _handle_execute_errror? out.ename = content['ename'] out.evalue = content['evalue'] out.traceback = content['traceback'] return elif msg_type == 'clear_output': self._current_cell['outputs'] = [] return elif msg_type == 'execute_reply': pass else: raise NotImplementedError('unhandled iopub message: %s' % msg_type) self._current_cell['outputs'].append(out) def _handle_kernel_died(self, since_last_heartbeat): """Handle the kernel's death (if we do not own the kernel). """ logging.warn("kernel died") self.reset() def _handle_kernel_restarted(self, died=True): """Notice that the autorestarter restarted the kernel. There's nothing to do but show a message. """ logging.warn("kernel restarted") self.reset() def _handle_execute_result(self, msg): """ Handle display hook output. """ logging.debug("execute_result: %s", msg.get('content', '')) if not self._hidden and self._is_from_this_session(msg): msg_id = msg['parent_header']['msg_id'] if msg_id not in self._cell_execute_ids: # Only on the in-process kernel can this happen self._result_queue.append(msg) return (cell, n, pc) = self._cell_execute_ids[msg_id] out = NotebookNode(output_type='display_data') for mime, data in msg['content']['data'].items(): try: attr = self.MIME_MAP[mime] except KeyError: raise NotImplementedError('unhandled mime type: %s' % mime) setattr(out, attr, data) cell['outputs'].append(out) def _handle_stream(self, msg): """ Handle stdout, stderr, and stdin. """ logging.debug("stream: %s", msg.get('content', '')) if not self._hidden and self._is_from_this_session(msg): logging.info(msg['content']['data']) def _handle_shutdown_reply(self, msg): """ Handle shutdown signal, only if from other console. """ logging.info("shutdown: %s", msg.get('content', '')) restart = msg.get('content', {}).get('restart', False) if not self._hidden and not self._is_from_this_session(msg): # got shutdown reply, request came from session other than ours if restart: # someone restarted the kernel, handle it self._handle_kernel_restarted(died=False) else: # kernel was shutdown permanently self.exit_requested.emit(self) def _handle_status(self, msg): """Handle status message""" # This is where a busy/idle indicator would be triggered, # when we make one. state = msg['content'].get('execution_state', '') if state == 'starting': # kernel started while we were running if self._executing: self._handle_kernel_restarted(died=True) elif state == 'idle': pass elif state == 'busy': pass #--------------------------------------------------------------------------- # 'FrontendWidget' public interface #--------------------------------------------------------------------------- def interrupt_kernel(self): """ Attempts to interrupt the running kernel. Also unsets _reading flag, to avoid runtime errors if raw_input is called again. """ self._reading = False self.kernel_manager.interrupt_kernel() def restart_kernel(self, message, now=False): """ Attempts to restart the running kernel. """ # Pause the heart beat channel to prevent further warnings. self.kernel_client.hb_channel.pause() try: self.kernel_manager.restart_kernel(now=now) except RuntimeError as e: logging.error('Error restarting kernel: %s\n' % e) else: logging.info("Restarting kernel...\n")
def getIPythonDialog(): from IPython.qt.console.rich_ipython_widget import RichIPythonWidget from IPython.qt.inprocess import QtInProcessKernelManager # from IPython.kernel.inprocess.ipkernel import InProcessKernel km = QtInProcessKernelManager() km.start_kernel() kernel = km.kernel kernel.gui = 'qt4' kernel_client = km.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() km.shutdown_kernel() class IPythonDialog(RichIPythonWidget, QVistrailsPaletteInterface): """This class incorporates an IPython shell into a dockable widget for use in the VisTrails environment""" def __init__(self, parent=None): RichIPythonWidget.__init__(self, parent) self.kernel_manager = km self.kernel_client = kernel_client self.exit_requested.connect(stop) #locals() returns the original dictionary, not a copy as #the docs say # self.firstLocals = copy.copy(locals()) # self.shell = IPythonXXX(self.firstLocals,None) # layout = QtGui.QVBoxLayout() # layout.setMargin(0) # layout.setSpacing(0) # layout.addWidget(self.shell) # self.setLayout(layout) # self.setWidget(self.shell) self.setWindowTitle("Console") # self.setTitleBarWidget(QtGui.QLabel(self.shell.windowTitle())) # self.monitorWindowTitle(self.shell) self.vistrails_interpreter = get_default_interpreter() def visibility_changed(self, visible): QVistrailsPaletteInterface.visibility_changed(self, visible) if visible: self.show() else: self.hide() def hide(self): """suspend() -> None Called when hiding the parent window in order to recover the previous state. """ #recovering the state sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ sys.stdin = sys.__stdin__ RichIPythonWidget.hide(self) def show(self): """show() -> None Store previous state and starts capturing all interactive input and output. """ # capture all interactive input/output sys.stdout = self sys.stderr = self sys.stdin = self RichIPythonWidget.show(self) def showEvent(self, e): """showEvent(e) -> None Event handler called when the dialog acquires focus """ self.show() def flush(self): """flush() -> None. Simulate stdin, stdout, and stderr. """ pass def isatty(self): """isatty() -> int Simulate stdin, stdout, and stderr. """ return 1 def readline(self): """readline() -> str Simulate stdin, stdout, and stderr. """ return "" def write(self, text): """write(text: str) -> None Simulate stdin, stdout, and stderr. """ self._append_plain_text(text, True) return IPythonDialog
class DataViewer(QtWidgets.QMainWindow): """ The class is used by instantiating and then entering the main Qt loop with, e.g.: app = DataViewer(sys.argv) app.exec_() """ def __init__(self, argv): """ Initialize class, setting up windows and widgets. """ # Define this as the QApplication object self.qtapp = QtWidgets.QApplication.instance() if not self.qtapp: self.qtapp = QtWidgets.QApplication(argv) QtWidgets.QMainWindow.__init__(self) self.this_dir, self.this_filename = os.path.split(__file__) # Make settings collection self.settings = LQCollection() # Set up sub-windows and arrange into primary py4DSTEM window self.diffraction_space_widget = self.setup_diffraction_space_widget() self.real_space_widget = self.setup_real_space_widget() self.control_widget = self.setup_control_widget() self.console_widget = self.setup_console_widget() self.main_window = self.setup_main_window() # Set up temporary datacube self.datacube = DataCube(data=np.zeros((10, 10, 10, 10))) # Set up initial views in real and diffraction space self.update_diffraction_space_view() self.update_virtual_detector_shape() self.update_virtual_detector_mode() self.update_real_space_view() self.diffraction_space_widget.ui.normDivideRadio.setChecked(True) self.diffraction_space_widget.normRadioChanged() return ############################################### ############ Widget setup methods ############# ############################################### def setup_control_widget(self): """ Set up the control window for diffraction space. """ #self.control_widget = load_qt_ui_file(sibling_path(__file__, "control_widget.ui")) self.control_widget = ControlPanel() self.control_widget.setWindowTitle("Control Panel") ############################ Controls ############################### # For each control: # # -creates items in self.settings # # -connects UI changes to updates in self.settings # # -connects updates in self.settings items to function calls # # -connects button clicks to function calls # ##################################################################### # Load self.settings.New('data_filename', dtype='file') self.settings.data_filename.connect_to_browse_widgets( self.control_widget.lineEdit_LoadFile, self.control_widget.pushButton_BrowseFiles) self.settings.data_filename.updated_value.connect(self.load_file) # Preprocess self.settings.New('R_Nx', dtype=int, initial=1) self.settings.New('R_Ny', dtype=int, initial=1) self.settings.New('bin_r', dtype=int, initial=1) self.settings.New('bin_q', dtype=int, initial=1) self.settings.New('crop_r_showROI', dtype=bool, initial=False) self.settings.New('crop_q_showROI', dtype=bool, initial=False) self.settings.New('isCropped_r', dtype=bool, initial=False) self.settings.New('isCropped_q', dtype=bool, initial=False) self.settings.New('crop_rx_min', dtype=int, initial=0) self.settings.New('crop_rx_max', dtype=int, initial=0) self.settings.New('crop_ry_min', dtype=int, initial=0) self.settings.New('crop_ry_max', dtype=int, initial=0) self.settings.New('crop_qx_min', dtype=int, initial=0) self.settings.New('crop_qx_max', dtype=int, initial=0) self.settings.New('crop_qy_min', dtype=int, initial=0) self.settings.New('crop_qy_max', dtype=int, initial=0) self.settings.R_Nx.connect_bidir_to_widget( self.control_widget.spinBox_Nx) self.settings.R_Ny.connect_bidir_to_widget( self.control_widget.spinBox_Ny) self.settings.bin_r.connect_bidir_to_widget( self.control_widget.spinBox_Bin_Real) self.settings.bin_q.connect_bidir_to_widget( self.control_widget.spinBox_Bin_Diffraction) self.settings.crop_r_showROI.connect_bidir_to_widget( self.control_widget.checkBox_Crop_Real) self.settings.crop_q_showROI.connect_bidir_to_widget( self.control_widget.checkBox_Crop_Diffraction) self.settings.R_Nx.updated_value.connect(self.update_scan_shape_Nx) self.settings.R_Ny.updated_value.connect(self.update_scan_shape_Ny) self.settings.crop_r_showROI.updated_value.connect( self.toggleCropROI_real) self.settings.crop_q_showROI.updated_value.connect( self.toggleCropROI_diffraction) self.control_widget.pushButton_CropData.clicked.connect(self.crop_data) self.control_widget.pushButton_BinData.clicked.connect(self.bin_data) self.control_widget.pushButton_EditFileMetadata.clicked.connect( self.edit_file_metadata) self.control_widget.pushButton_EditDirectoryMetadata.clicked.connect( self.edit_directory_metadata) self.control_widget.pushButton_SaveFile.clicked.connect(self.save_file) self.control_widget.pushButton_SaveDirectory.clicked.connect( self.save_directory) # Virtual detectors self.settings.New('virtual_detector_shape', dtype=int, initial=0) self.settings.New('virtual_detector_mode', dtype=int, initial=0) self.settings.virtual_detector_shape.connect_bidir_to_widget( self.control_widget.buttonGroup_DetectorShape) self.settings.virtual_detector_mode.connect_bidir_to_widget( self.control_widget.buttonGroup_DetectorMode) self.settings.virtual_detector_shape.updated_value.connect( self.update_virtual_detector_shape) self.settings.virtual_detector_mode.updated_value.connect( self.update_virtual_detector_mode) return self.control_widget def setup_diffraction_space_widget(self): """ Set up the diffraction space window. """ # Create pyqtgraph ImageView object self.diffraction_space_widget = pg.ImageView() self.diffraction_space_widget.setImage(np.zeros((512, 512))) # Create virtual detector ROI selector self.virtual_detector_roi = pg.RectROI([256, 256], [50, 50], pen=(3, 9)) self.diffraction_space_widget.getView().addItem( self.virtual_detector_roi) self.virtual_detector_roi.sigRegionChangeFinished.connect( self.update_real_space_view) # Name and return self.diffraction_space_widget.setWindowTitle('Diffraction Space') return self.diffraction_space_widget def setup_real_space_widget(self): """ Set up the real space window. """ # Create pyqtgraph ImageView object self.real_space_widget = pg.ImageView() self.real_space_widget.setImage(np.zeros((512, 512))) # Add point selector connected to displayed diffraction pattern self.real_space_point_selector = pg_point_roi( self.real_space_widget.getView()) self.real_space_point_selector.sigRegionChanged.connect( self.update_diffraction_space_view) # Name and return self.real_space_widget.setWindowTitle('Real Space') return self.real_space_widget def setup_console_widget(self): self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push({'np': np, 'app': self}) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.console_widget = RichJupyterWidget() self.console_widget.setWindowTitle("py4DSTEM IPython Console") self.console_widget.kernel_manager = self.kernel_manager self.console_widget.kernel_client = self.kernel_client return self.console_widget def setup_main_window(self): """ Setup main window, arranging sub-windows inside """ self.main_window = QtWidgets.QWidget() self.main_window.setWindowTitle("py4DSTEM") layout_data = QtWidgets.QHBoxLayout() layout_data.addWidget(self.diffraction_space_widget, 1) layout_data.addWidget(self.real_space_widget, 1) layout_data_and_control = QtWidgets.QHBoxLayout() layout_data_and_control.addWidget(self.control_widget, 0) layout_data_and_control.addLayout(layout_data, 1) layout_data_and_control.setSpacing(0) layout_data_and_control.setContentsMargins(0, 0, 0, 0) self.main_window.setLayout(layout_data_and_control) self.main_window.setGeometry(0, 0, 3600, 1600) self.console_widget.setGeometry(0, 1800, 1600, 250) self.main_window.show() self.main_window.raise_() self.console_widget.show() self.console_widget.raise_() return self.main_window ################################################################## ############## Methods connecting to user inputs ################# ################################################################## ################################################################## # In general, these methods collect any relevant user inputs, # # then pass them to functions defined elsewhere, often in e.g. # # the process directory. # # Additional functionality here should be avoided, to ensure # # consistent output between processing run through the GUI # # or from the command line. # ################################################################## ################ Load ################ def load_file(self): """ Loads a file by creating and storing a DataCube object. """ fname = self.settings.data_filename.val print("Loading file", fname) # Instantiate DataCube object self.datacube = None gc.collect() self.datacube = read(fname) # Update scan shape information self.settings.R_Nx.update_value(self.datacube.R_Nx) self.settings.R_Ny.update_value(self.datacube.R_Ny) # Update data views self.update_diffraction_space_view() self.update_virtual_detector_shape() self.update_virtual_detector_mode() self.update_real_space_view() # Normalize diffraction space view self.diffraction_space_widget.ui.normDivideRadio.setChecked(True) self.diffraction_space_widget.normRadioChanged() # Set scan size maxima self.control_widget.spinBox_Nx.setMaximum(self.datacube.R_N) self.control_widget.spinBox_Ny.setMaximum(self.datacube.R_N) return ############## Preprocess ############## ### Scan Shape ### def update_scan_shape_Nx(self): R_Nx = self.settings.R_Nx.val self.settings.R_Ny.update_value(int(self.datacube.R_N / R_Nx)) R_Ny = self.settings.R_Ny.val self.datacube.set_scan_shape(R_Nx, R_Ny) self.update_real_space_view() def update_scan_shape_Ny(self): R_Ny = self.settings.R_Ny.val self.settings.R_Nx.update_value(int(self.datacube.R_N / R_Ny)) R_Nx = self.settings.R_Nx.val self.datacube.set_scan_shape(R_Nx, R_Ny) self.update_real_space_view() ### Crop ### def toggleCropROI_real(self, show=True): """ If show=True, makes an RIO. If False, removes the ROI. """ if show: self.crop_roi_real = pg.RectROI( [0, 0], [self.datacube.R_Nx, self.datacube.R_Ny], pen=(3, 9), removable=True, translateSnap=True, scaleSnap=True) self.crop_roi_real.setPen(color='r') self.real_space_widget.getView().addItem(self.crop_roi_real) else: if hasattr(self, 'crop_roi_real'): self.real_space_widget.getView().removeItem(self.crop_roi_real) self.crop_roi_real = None else: pass def toggleCropROI_diffraction(self, show=True): """ If show=True, makes an RIO. If False, removes the ROI. """ if show: self.crop_roi_diffraction = pg.RectROI( [0, 0], [self.datacube.Q_Nx, self.datacube.Q_Ny], pen=(3, 9), removable=True, translateSnap=True, scaleSnap=True) self.crop_roi_diffraction.setPen(color='r') self.diffraction_space_widget.getView().addItem( self.crop_roi_diffraction) else: if hasattr(self, 'crop_roi_diffraction'): self.diffraction_space_widget.getView().removeItem( self.crop_roi_diffraction) self.crop_roi_diffraction = None else: pass def crop_data(self): # Diffraction space if self.control_widget.checkBox_Crop_Diffraction.isChecked(): # Get crop limits from ROI slices_q, transforms_q = self.crop_roi_diffraction.getArraySlice( self.datacube.data4D[0, 0, :, :], self.diffraction_space_widget.getImageItem()) slice_qx, slice_qy = slices_q crop_Qx_min, crop_Qx_max = slice_qx.start, slice_qx.stop - 1 crop_Qy_min, crop_Qy_max = slice_qy.start, slice_qy.stop - 1 crop_Qx_min, crop_Qx_max = max(0, crop_Qx_min), min( self.datacube.Q_Nx, crop_Qx_max) crop_Qy_min, crop_Qy_max = max(0, crop_Qy_min), min( self.datacube.Q_Ny, crop_Qy_max) # Move ROI selector x0, y0 = self.virtual_detector_roi.x( ), self.virtual_detector_roi.y() x0_len, y0_len = self.virtual_detector_roi.size() xf = int(x0 * (crop_Qx_max - crop_Qx_min) / self.datacube.Q_Nx) yf = int(y0 * (crop_Qy_max - crop_Qy_min) / self.datacube.Q_Ny) xf_len = int(x0_len * (crop_Qx_max - crop_Qx_min) / self.datacube.Q_Nx) yf_len = int(y0_len * (crop_Qy_max - crop_Qy_min) / self.datacube.Q_Ny) self.virtual_detector_roi.setPos((xf, yf)) self.virtual_detector_roi.setSize((xf_len, yf_len)) # Crop data self.datacube.crop_data_diffraction(crop_Qx_min, crop_Qx_max, crop_Qy_min, crop_Qy_max) # Update settings self.settings.crop_qx_min.update_value(crop_Qx_min) self.settings.crop_qx_max.update_value(crop_Qx_max) self.settings.crop_qy_min.update_value(crop_Qy_min) self.settings.crop_qy_max.update_value(crop_Qy_max) self.settings.isCropped_q.update_value(True) # Uncheck crop checkbox and remove ROI self.control_widget.checkBox_Crop_Diffraction.setChecked(False) # Update display self.update_diffraction_space_view() else: self.settings.isCropped_q.update_value(False) # Real space if self.control_widget.checkBox_Crop_Real.isChecked(): # Get crop limits from ROI slices_r, transforms_r = self.crop_roi_real.getArraySlice( self.datacube.data4D[:, :, 0, 0], self.real_space_widget.getImageItem()) slice_rx, slice_ry = slices_r crop_Rx_min, crop_Rx_max = slice_rx.start, slice_rx.stop - 1 crop_Ry_min, crop_Ry_max = slice_ry.start, slice_ry.stop - 1 crop_Rx_min, crop_Rx_max = max(0, crop_Rx_min), min( self.datacube.R_Nx, crop_Rx_max) crop_Ry_min, crop_Ry_max = max(0, crop_Ry_min), min( self.datacube.R_Ny, crop_Ry_max) # Move point selector x0, y0 = self.real_space_point_selector.x( ), self.real_space_point_selector.y() xf = int(x0 * (crop_Rx_max - crop_Rx_min) / self.datacube.R_Nx) yf = int(y0 * (crop_Ry_max - crop_Ry_min) / self.datacube.R_Ny) self.real_space_point_selector.setPos((xf, yf)) # Crop data self.datacube.crop_data_real(crop_Rx_min, crop_Rx_max, crop_Ry_min, crop_Ry_max) # Update settings self.settings.crop_rx_min.update_value(crop_Rx_min) self.settings.crop_rx_max.update_value(crop_Rx_max) self.settings.crop_ry_min.update_value(crop_Ry_min) self.settings.crop_ry_max.update_value(crop_Ry_max) self.settings.isCropped_r.update_value(True) self.settings.R_Nx.update_value(self.datacube.R_Nx, send_signal=False) self.settings.R_Ny.update_value(self.datacube.R_Ny, send_signal=False) # Uncheck crop checkbox and remove ROI self.control_widget.checkBox_Crop_Real.setChecked(False) # Update display self.update_real_space_view() else: self.settings.isCropped_r.update_value(False) ### Bin ### def bin_data(self): # Get bin factors from GUI bin_factor_Q = self.settings.bin_q.val bin_factor_R = self.settings.bin_r.val if bin_factor_Q > 1: # Move ROI selector x0, y0 = self.virtual_detector_roi.x( ), self.virtual_detector_roi.y() x0_len, y0_len = self.virtual_detector_roi.size() xf = int(x0 / bin_factor_Q) yf = int(y0 / bin_factor_Q) xf_len = int(x0_len / bin_factor_Q) yf_len = int(y0_len / bin_factor_Q) self.virtual_detector_roi.setPos((xf, yf)) self.virtual_detector_roi.setSize((xf_len, yf_len)) # Bin data self.datacube.bin_data_diffraction(bin_factor_Q) # Update display self.update_diffraction_space_view() if bin_factor_R > 1: # Move point selector x0, y0 = self.real_space_point_selector.x( ), self.real_space_point_selector.y() xf = int(x0 / bin_factor_R) yf = int(y0 / bin_factor_R) self.real_space_point_selector.setPos((xf, yf)) # Bin data self.datacube.bin_data_real(bin_factor_R) # Update settings self.settings.R_Nx.update_value(self.datacube.R_Nx, send_signal=False) self.settings.R_Ny.update_value(self.datacube.R_Ny, send_signal=False) # Update display self.update_real_space_view() # Set bin factors back to 1 self.settings.bin_q.update_value(1) self.settings.bin_r.update_value(1) ### Metadata ### def edit_file_metadata(self): """ Creates a popup dialog with tabs for different metadata groups, and fields in each group with current, editable metadata values. """ # Make widget self.EditMetadataWidget = EditMetadataWidget(self.datacube) self.EditMetadataWidget.setWindowTitle("Metadata Editor") self.EditMetadataWidget.show() self.EditMetadataWidget.raise_() # Cancel or save self.EditMetadataWidget.pushButton_Cancel.clicked.connect( self.cancel_editMetadata) self.EditMetadataWidget.pushButton_Save.clicked.connect( self.save_editMetadata) def cancel_editMetadata(self): self.EditMetadataWidget.close() def save_editMetadata(self): print("Updating metadata...") for i in range(self.EditMetadataWidget.tabs.count()): tab = self.EditMetadataWidget.tabs.widget(i) # Get appropriate metadata dict tabname = self.EditMetadataWidget.tabs.tabText(i) metadata_dict_name = [ name for name in self.datacube.metadata.__dict__.keys() if tabname[1:] in name ][0] metadata_dict = getattr(self.datacube.metadata, metadata_dict_name) for row in tab.layout().children(): key = row.itemAt(0).widget().text() try: value = row.itemAt(1).widget().text() except AttributeError: # Catches alternate widget (QPlainTextEdit) in comments tab value = row.itemAt(1).widget().toPlainText() try: value = float(value) except ValueError: pass metadata_dict[key] = value self.EditMetadataWidget.close() print("Done.") def edit_directory_metadata(self): print('edit directory metadata pressed') pass ### Save ### def save_file(self): """ Saving files to the .h5 format. This method: 1) opens a separate dialog 2) puts a name in the "Save as:" field according to the original filename and any preprocessing that's been done 2) Exits with or without saving when 'Save' or 'Cancel' buttons are pressed. """ # Make widget save_path = os.path.splitext( self.settings.data_filename.val)[0] + '.h5' self.save_widget = SaveWidget(save_path) self.save_widget.setWindowTitle("Save as...") self.save_widget.show() self.save_widget.raise_() # Cancel or save self.save_widget.pushButton_Cancel.clicked.connect(self.cancel_saveas) self.save_widget.pushButton_Execute.clicked.connect( self.execute_saveas) def cancel_saveas(self): self.save_widget.close() def execute_saveas(self): f = self.save_widget.lineEdit_SavePath.text() print("Saving file to {}".format(f)) save_dataobject(self.datacube, f) self.save_widget.close() def save_directory(self): print('save directory metadata pressed') pass ################# Virtual Detectors ################# def update_virtual_detector_shape(self): """ Virtual detector shapes are mapped to integers, following the IDs assigned to the radio buttons in VirtualDetectorWidget in dialogs.py. They are as follows: 1: Rectangular 2: Circular 3: Annular """ detector_shape = self.settings.virtual_detector_shape.val x, y = self.diffraction_space_view.shape x0, y0 = x / 2, y / 2 xr, yr = x / 10, y / 10 # Remove existing detector if hasattr(self, 'virtual_detector_roi'): self.diffraction_space_widget.view.scene().removeItem( self.virtual_detector_roi) if hasattr(self, 'virtual_detector_roi_inner'): self.diffraction_space_widget.view.scene().removeItem( self.virtual_detector_roi_inner) if hasattr(self, 'virtual_detector_roi_outer'): self.diffraction_space_widget.view.scene().removeItem( self.virtual_detector_roi_outer) # Rectangular detector if detector_shape == 0: self.virtual_detector_roi = pg.RectROI( [int(x0 - xr / 2), int(y0 - yr / 2)], [int(xr), int(yr)], pen=(3, 9)) self.diffraction_space_widget.getView().addItem( self.virtual_detector_roi) self.virtual_detector_roi.sigRegionChangeFinished.connect( self.update_real_space_view) # Circular detector elif detector_shape == 1: self.virtual_detector_roi = pg.CircleROI( [int(x0 - xr / 2), int(y0 - yr / 2)], [int(xr), int(yr)], pen=(3, 9)) self.diffraction_space_widget.getView().addItem( self.virtual_detector_roi) self.virtual_detector_roi.sigRegionChangeFinished.connect( self.update_real_space_view) # Annular dector elif detector_shape == 2: # Make outer detector self.virtual_detector_roi_outer = pg.CircleROI( [int(x0 - xr), int(y0 - yr)], [int(2 * xr), int(2 * yr)], pen=(3, 9)) self.diffraction_space_widget.getView().addItem( self.virtual_detector_roi_outer) # Make inner detector self.virtual_detector_roi_inner = pg.CircleROI( [int(x0 - xr / 2), int(y0 - yr / 2)], [int(xr), int(yr)], pen=(4, 9), movable=False) self.diffraction_space_widget.getView().addItem( self.virtual_detector_roi_inner) # Connect size/position of inner and outer detectors self.virtual_detector_roi_outer.sigRegionChangeFinished.connect( self.update_annulus_pos) self.virtual_detector_roi_outer.sigRegionChangeFinished.connect( self.update_annulus_radii) self.virtual_detector_roi_inner.sigRegionChangeFinished.connect( self.update_annulus_radii) # Connect to real space view update function self.virtual_detector_roi_outer.sigRegionChangeFinished.connect( self.update_real_space_view) self.virtual_detector_roi_inner.sigRegionChangeFinished.connect( self.update_real_space_view) else: raise ValueError( "Unknown detector shape value {}. Must be 0, 1, or 2.".format( detector_shape)) self.update_virtual_detector_mode() self.update_real_space_view() def update_annulus_pos(self): """ Function to keep inner and outer rings of annulus aligned. """ R_outer = self.virtual_detector_roi_outer.size().x() / 2 R_inner = self.virtual_detector_roi_inner.size().x() / 2 # Only outer annulus is draggable; when it moves, update position of inner annulus x0 = self.virtual_detector_roi_outer.pos().x() + R_outer y0 = self.virtual_detector_roi_outer.pos().y() + R_outer self.virtual_detector_roi_inner.setPos(x0 - R_inner, y0 - R_inner) def update_annulus_radii(self): R_outer = self.virtual_detector_roi_outer.size().x() / 2 R_inner = self.virtual_detector_roi_inner.size().x() / 2 if R_outer < R_inner: x0 = self.virtual_detector_roi_outer.pos().x() + R_outer y0 = self.virtual_detector_roi_outer.pos().y() + R_outer self.virtual_detector_roi_outer.setSize(2 * R_inner + 6) self.virtual_detector_roi_outer.setPos(x0 - R_inner - 3, y0 - R_inner - 3) def update_virtual_detector_mode(self): """ Virtual detector modes are mapped to integers, following the IDs assigned to the radio buttons in VirtualDetectorWidget in dialogs.py. They are as follows: 0: Integrate 1: Difference, X 2: Difference, Y 3: CoM, Y 4: CoM, X """ detector_mode = self.settings.virtual_detector_mode.val detector_shape = self.settings.virtual_detector_shape.val # Integrating detector if detector_mode == 0: if detector_shape == 0: self.get_virtual_image = self.datacube.get_virtual_image_rect_integrate elif detector_shape == 1: self.get_virtual_image = self.datacube.get_virtual_image_circ_integrate elif detector_shape == 2: self.get_virtual_image = self.datacube.get_virtual_image_annular_integrate else: raise ValueError( "Unknown detector shape value {}".format(detector_shape)) # Difference detector elif detector_mode == 1: if detector_shape == 0: self.get_virtual_image = self.datacube.get_virtual_image_rect_diffX elif detector_shape == 1: self.get_virtual_image = self.datacube.get_virtual_image_circ_diffX elif detector_shape == 2: self.get_virtual_image = self.datacube.get_virtual_image_annular_diffX else: raise ValueError( "Unknown detector shape value {}".format(detector_shape)) elif detector_mode == 2: if detector_shape == 0: self.get_virtual_image = self.datacube.get_virtual_image_rect_diffY elif detector_shape == 1: self.get_virtual_image = self.datacube.get_virtual_image_circ_diffY elif detector_shape == 2: self.get_virtual_image = self.datacube.get_virtual_image_annular_diffY else: raise ValueError( "Unknown detector shape value {}".format(detector_shape)) # CoM detector elif detector_mode == 3: if detector_shape == 0: self.get_virtual_image = self.datacube.get_virtual_image_rect_CoMX elif detector_shape == 1: self.get_virtual_image = self.datacube.get_virtual_image_circ_CoMX elif detector_shape == 2: self.get_virtual_image = self.datacube.get_virtual_image_annular_CoMX else: raise ValueError( "Unknown detector shape value {}".format(detector_shape)) elif detector_mode == 4: if detector_shape == 0: self.get_virtual_image = self.datacube.get_virtual_image_rect_CoMY elif detector_shape == 1: self.get_virtual_image = self.datacube.get_virtual_image_circ_CoMY elif detector_shape == 2: self.get_virtual_image = self.datacube.get_virtual_image_annular_CoMY else: raise ValueError( "Unknown detector shape value {}".format(detector_shape)) else: raise ValueError( "Unknown detector mode value {}".format(detector_mode)) self.update_real_space_view() ################## Get virtual images ################## def update_diffraction_space_view(self): roi_state = self.real_space_point_selector.saveState() x0, y0 = roi_state['pos'] xc, yc = int(x0 + 1), int(y0 + 1) # Set the diffraction space image new_diffraction_space_view, success = self.datacube.get_diffraction_space_view( xc, yc) if success: self.diffraction_space_view = new_diffraction_space_view self.diffraction_space_widget.setImage(self.diffraction_space_view, autoLevels=False, autoRange=False) else: pass return def update_real_space_view(self): detector_shape = self.settings.virtual_detector_shape.val # Rectangular detector if detector_shape == 0: # Get slices corresponding to ROI slices, transforms = self.virtual_detector_roi.getArraySlice( self.datacube.data4D[0, 0, :, :], self.diffraction_space_widget.getImageItem()) slice_x, slice_y = slices # Get the virtual image and set the real space view new_real_space_view, success = self.get_virtual_image( slice_x, slice_y) if success: self.real_space_view = new_real_space_view self.real_space_widget.setImage(self.real_space_view, autoLevels=True) else: pass # Circular detector elif detector_shape == 1: # Get slices corresponding to ROI slices, transforms = self.virtual_detector_roi.getArraySlice( self.datacube.data4D[0, 0, :, :], self.diffraction_space_widget.getImageItem()) slice_x, slice_y = slices # Get the virtual image and set the real space view new_real_space_view, success = self.get_virtual_image( slice_x, slice_y) if success: self.real_space_view = new_real_space_view self.real_space_widget.setImage(self.real_space_view, autoLevels=True) else: pass # Annular detector elif detector_shape == 2: # Get slices corresponding to ROI slices, transforms = self.virtual_detector_roi_outer.getArraySlice( self.datacube.data4D[0, 0, :, :], self.diffraction_space_widget.getImageItem()) slice_x, slice_y = slices slices_inner, transforms = self.virtual_detector_roi_inner.getArraySlice( self.datacube.data4D[0, 0, :, :], self.diffraction_space_widget.getImageItem()) slice_inner_x, slice_inner_y = slices_inner R = 0.5 * ((slice_inner_x.stop - slice_inner_x.start) / (slice_x.stop - slice_x.start) + (slice_inner_y.stop - slice_inner_y.start) / (slice_y.stop - slice_y.start)) # Get the virtual image and set the real space view new_real_space_view, success = self.get_virtual_image( slice_x, slice_y, R) if success: self.real_space_view = new_real_space_view self.real_space_widget.setImage(self.real_space_view, autoLevels=True) else: pass else: print( "Error: unknown detector shape value {}. Must be 0, 1, or 2.". format(detector_shape)) return def exec_(self): return self.qtapp.exec_()
class QtipWindow(QtGui.QMainWindow): """ Main Qtip window Note, is the main window now, but the content will later be moved to a libstempo tab, as part of the Piccard suite """ def __init__(self, parent=None, engine='libstempo', \ parfile=None, timfile=None, **kwargs): super(QtipWindow, self).__init__(parent) self.setWindowTitle('QtIpython interface to Piccard/libstempo') # Initialise basic gui elements self.initUI() # Start the embedded IPython kernel self.createIPythonKernel() # Create the display widgets self.createBinaryWidget() self.createPlkWidget() self.createIPythonWidget() self.createOpenSomethingWidget() # Position the widgets self.initQtipLayout() self.setQtipLayout(whichWidget='opensomething', showIPython=False, firsttime=True) # We are still in MAJOR testing mode, so open a test-pulsar right away # (delete this line when going into production) if parfile is None or timfile is None: testpulsar = True else: testpulsar = False # Are we going to open plk straight away? self.requestOpenPlk(testpulsar=testpulsar, parfilename=parfile, \ timfilename=timfile, engine=engine) self.show() def __del__(self): pass def onAbout(self): msg = """ A plk emulator, written in Python. Powered by PyQt, matplotlib, libstempo, and IPython: """ QtGui.QMessageBox.about(self, "About the demo", msg.strip()) def initUI(self): """ Initialise the user-interface elements """ # Create the main-frame widget, and the layout self.mainFrame = QtGui.QWidget() self.setCentralWidget(self.mainFrame) self.hbox = QtGui.QHBoxLayout() # HBox contains all widgets # Create the menu action items self.openParTimAction = QtGui.QAction('&Open', self) self.openParTimAction.setShortcut('Ctrl+O') self.openParTimAction.setStatusTip('Open par/tim') self.openParTimAction.triggered.connect(self.openParTim) self.exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&Exit', self) self.exitAction.setShortcut('Ctrl+Q') self.exitAction.setStatusTip('Exit application') self.exitAction.triggered.connect(self.close) self.toggleBinaryAction = QtGui.QAction('&Binary', self) self.toggleBinaryAction.setShortcut('Ctrl+B') self.toggleBinaryAction.setStatusTip('Toggle binary widget') self.toggleBinaryAction.triggered.connect(self.toggleBinary) self.togglePlkAction = QtGui.QAction('&Plk', self) self.togglePlkAction.setShortcut('Ctrl+P') self.togglePlkAction.setStatusTip('Toggle plk widget') self.togglePlkAction.triggered.connect(self.togglePlk) self.toggleIPythonAction = QtGui.QAction('&IPython', self) self.toggleIPythonAction.setShortcut('Ctrl+I') self.toggleIPythonAction.setStatusTip('Toggle IPython') self.toggleIPythonAction.triggered.connect(self.toggleIPython) self.aboutAction = QtGui.QAction('&About', self) self.aboutAction.setShortcut('Ctrl+A') self.aboutAction.setStatusTip('About Qtip') self.aboutAction.triggered.connect(self.onAbout) self.theStatusBar = QtGui.QStatusBar() #self.statusBar() self.setStatusBar(self.theStatusBar) self.engine_label = QtGui.QLabel("Tempo2") self.engine_label.setFrameStyle(QtGui.QFrame.Sunken | QtGui.QFrame.Panel) self.engine_label.setLineWidth(4) self.engine_label.setMidLineWidth(4) self.engine_label.setStyleSheet( "QLabel{color:black;background-color:red}") self.theStatusBar.addPermanentWidget(self.engine_label) # On OSX, make sure the menu can be displayed (in the window itself) if sys.platform == 'darwin': # On OSX, the menubar is usually on the top of the screen, not in # the window. To make it in the window: QtGui.qt_mac_set_native_menubar(False) # Otherwise, if we'd like to get the system menubar at the top, then # we need another menubar object, not self.menuBar as below. In that # case, use: # self.menubar = QtGui.QMenuBar() # TODO: Somehow this does not work. Per-window one does though # Create the menu self.menubar = self.menuBar() self.fileMenu = self.menubar.addMenu('&File') self.fileMenu.addAction(self.openParTimAction) self.fileMenu.addAction(self.exitAction) self.viewMenu = self.menubar.addMenu('&View') self.viewMenu.addAction(self.toggleBinaryAction) self.viewMenu.addAction(self.togglePlkAction) self.viewMenu.addAction(self.toggleIPythonAction) self.helpMenu = self.menubar.addMenu('&Help') self.helpMenu.addAction(self.aboutAction) # What is the status quo of the user interface? self.showIPython = False self.whichWidget = 'None' self.prevShowIPython = None self.prevWhichWidget = 'None' def createIPythonKernel(self): """ Create the IPython Kernel """ # Create an in-process kernel self.kernelManager = QtInProcessKernelManager() self.kernelManager.start_kernel() self.kernel = self.kernelManager.kernel self.kernelClient = self.kernelManager.client() self.kernelClient.start_channels() self.kernel.shell.enable_matplotlib(gui='inline') # Load the necessary packages in the embedded kernel cell = "import numpy as np, matplotlib.pyplot as plt, qtpulsar as qp" self.kernel.shell.run_cell(cell, store_history=False) # Set the in-kernel matplotlib color scheme to black. self.setMplColorScheme('black') # Outside as well (do we need this?) self.kernel.shell.run_cell(constants.matplotlib_rc_cell_black, store_history=False) def createIPythonWidget(self): """ Create the IPython widget """ self.consoleWidget = RichIPythonWidget() #self.consoleWidget.setMinimumSize(600, 550) self.consoleWidget.banner = QtipBanner self.consoleWidget.kernel_manager = self.kernelManager self.consoleWidget.kernel_client = self.kernelClient self.consoleWidget.exit_requested.connect(self.toggleIPython) self.consoleWidget.set_default_style(colors='linux') self.consoleWidget.hide() # Register a call-back function for the IPython shell. This one is # executed insite the child-kernel. #self.kernel.shell.register_post_execute(self.postExecute) # # In IPython >= 2, we can use the event register # Events: post_run_cell, pre_run_cell, etc...` self.kernel.shell.events.register('pre_execute', self.preExecute) self.kernel.shell.events.register('post_execute', self.postExecute) self.kernel.shell.events.register('post_run_cell', self.postRunCell) def createOpenSomethingWidget(self): """ Create the OpenSomething widget. Do not add it to the layout yet TODO: probably should use a signal to implement this call instead of openParTim """ self.openSomethingWidget = OpenSomethingWidget(parent=self.mainFrame, \ openFile=self.requestOpenPlk) self.openSomethingWidget.hide() def createPlkWidget(self): """ Create the Plk widget """ self.plkWidget = PlkWidget(parent=self.mainFrame) self.plkWidget.hide() def createBinaryWidget(self): """ Create the binary model widget """ self.binaryWidget = BinaryWidget(parent=self.mainFrame) self.binaryWidget.hide() def toggleIPython(self): """ Toggle the IPython widget on or off """ self.setQtipLayout(showIPython=not self.showIPython) def toggleBinary(self): """ Toggle the binary model widget on or off """ self.setQtipLayout(whichWidget='binary') def togglePlk(self): """ Toggle the plk widget on or off """ self.setQtipLayout(whichWidget='plk') def initQtipLayout(self): """ Initialise the Qtip layout """ self.hbox.addWidget(self.openSomethingWidget) self.hbox.addWidget(self.plkWidget) self.hbox.addWidget(self.binaryWidget) self.hbox.addStretch(1) self.hbox.addWidget(self.consoleWidget) self.mainFrame.setLayout(self.hbox) def hideAllWidgets(self): """ Hide all widgets of the mainFrame """ # Remove all widgets from the main window # ??? """ while self.hbox.count(): item = self.hbox.takeAt(0) if isinstance(item, QtGui.QWidgetItem): #item.widget().deleteLater() item.widget().hide() elif isinstance(item, QtGui.QSpacerItem): #self.hbox.removeItem(item) pass else: #fcbox.clearLayout(item.layout()) #self.hbox.removeItem(item) pass """ self.openSomethingWidget.hide() self.plkWidget.hide() self.binaryWidget.hide() self.consoleWidget.hide() def showVisibleWidgets(self): """ Show the correct widgets in the mainFrame """ # Add the widgets we need if self.whichWidget.lower() == 'opensomething': self.openSomethingWidget.show() elif self.whichWidget.lower() == 'plk': self.plkWidget.show() elif self.whichWidget.lower() == 'piccard': pass elif self.whichWidget.lower() == 'binary': self.binaryWidget.show() if self.showIPython: self.consoleWidget.show() else: pass if self.whichWidget.lower() == 'plk' and not self.showIPython: self.plkWidget.setFocusToCanvas() elif self.whichWidget.lower() == 'binary' and not self.showIPython: self.binaryWidget.setFocusToCanvas() #elif self.showIPython: # self.consoleWidget.setFocus() def setQtipLayout(self, whichWidget=None, showIPython=None, firsttime=False): """ Given which widgets to show, display the right widgets and hide the rest @param whichWidget: Which widget to show @param showIPython: Whether to show the IPython console """ if not whichWidget is None: self.whichWidget = whichWidget if not showIPython is None: self.showIPython = showIPython # After hiding the widgets, wait 25 (or 0?) miliseconds before showing them again self.hideAllWidgets() QtCore.QTimer.singleShot(0, self.showVisibleWidgets) self.prevWhichWidget = self.whichWidget if self.showIPython != self.prevShowIPython: # IPython has been toggled self.prevShowIPython = self.showIPython if self.showIPython: self.resize(1350, 550) self.mainFrame.resize(1350, 550) else: self.resize(650, 550) self.mainFrame.resize(650, 550) if firsttime: # Set position slightly more to the left of the screen, so we can # still open IPython self.move(200, 100) self.mainFrame.setLayout(self.hbox) self.mainFrame.show() def requestOpenPlk(self, parfilename=None, timfilename=None, \ testpulsar=False, engine='libstempo'): """ Request to open a file in the plk widget @param parfilename: The parfile to open. If none, ask the user @param timfilename: The timfile to open. If none, ask the user """ self.setQtipLayout(whichWidget='plk', showIPython=self.showIPython) if parfilename is None and not testpulsar: parfilename = QtGui.QFileDialog.getOpenFileName( self, 'Open par-file', '~/') if timfilename is None and not testpulsar: timfilename = QtGui.QFileDialog.getOpenFileName( self, 'Open tim-file', '~/') # Load the pulsar self.openPulsar(parfilename, timfilename, engine=engine, \ testpulsar=testpulsar) def setMplColorScheme(self, scheme): """ Set the matplotlib color scheme @param scheme: 'black'/'white', the color scheme """ # Obtain the Widget background color color = self.palette().color(QtGui.QPalette.Window) r, g, b = color.red(), color.green(), color.blue() rgbcolor = (r / 255.0, g / 255.0, b / 255.0) if scheme == 'white': rcP = constants.mpl_rcParams_white rcP['axes.facecolor'] = rgbcolor rcP['figure.facecolor'] = rgbcolor rcP['figure.edgecolor'] = rgbcolor rcP['savefig.facecolor'] = rgbcolor rcP['savefig.edgecolor'] = rgbcolor elif scheme == 'black': rcP = constants.mpl_rcParams_black for key, value in rcP.iteritems(): matplotlib.rcParams[key] = value def openParTim(self, filename=None, engine='libstempo'): """ Open a par-file and a tim-file """ print("openParTim called with {0}".format(filename)) # Ask the user for a par and tim file, and open these with libstempo if isinstance(filename, str): parfilename = filename else: parfilename = QtGui.QFileDialog.getOpenFileName( self, 'Open par-file', '~/') timfilename = QtGui.QFileDialog.getOpenFileName( self, 'Open tim-file', '~/') # Load the pulsar self.openPulsar(parfilename, timfilename, engine=engine) def openPulsar(self, parfilename, timfilename, engine='libstempo', testpulsar=False): """ Open a pulsar, given a parfile and a timfile @param parfilename: The name of the parfile to open @param timfilename: The name fo the timfile to open @param engine: Which pulsar timing engine to use [libstempo] @param testpulsar: If True, open the test pulsar (J1744, NANOGrav) """ if engine == 'pint': trypint = True else: trypint = False self.engine, pclass = qp.get_engine(trypint=trypint) if engine == 'libstempo': if not testpulsar: # Obtain the directory name of the timfile, and change to it timfiletup = os.path.split(timfilename) dirname = timfiletup[0] reltimfile = timfiletup[-1] relparfile = os.path.relpath(parfilename, dirname) savedir = os.getcwd() # Change directory to the base directory of the tim-file to deal with # INCLUDE statements in the tim-file os.chdir(dirname) # Load the pulsar cell = "psr = qp." + pclass + "('" + relparfile + "', '" + reltimfile + "')" self.kernel.shell.run_cell(cell) psr = self.kernel.shell.ns_table['user_local']['psr'] # Change directory back to where we were os.chdir(savedir) else: cell = "psr = qp." + pclass + "(testpulsar=True)" self.kernel.shell.run_cell(cell) psr = self.kernel.shell.ns_table['user_local']['psr'] elif engine == 'pint': cell = "psr = qp." + pclass + "(testpulsar=True)" self.kernel.shell.run_cell(cell) psr = self.kernel.shell.ns_table['user_local']['psr'] else: raise NotImplemented("Only works with PINT/libstempo") # Update the plk widget self.plkWidget.setPulsar(psr) self.binaryWidget.setPulsar(psr) # Communicating with the kernel goes as follows # self.kernel.shell.push({'foo': 43, 'print_process_id': print_process_id}, interactive=True) # print("Embedded, we have:", self.kernel.shell.ns_table['user_local']['foo']) def keyPressEvent(self, event, **kwargs): """ Handle a key-press event @param event: event that is handled here """ key = event.key() if key == QtCore.Qt.Key_Escape: self.close() elif key == QtCore.Qt.Key_Left: #print("Left pressed") pass else: #print("Other key") pass #print("QtipWindow: key press") super(QtipWindow, self).keyPressEvent(event, **kwargs) def mousePressEvent(self, event, **kwargs): """ Handle a mouse-click event @param event: event that is handled here """ #print("QtipWindow: mouse click") super(QtipWindow, self).mousePressEvent(event, **kwargs) def preExecute(self): """ Callback function that is run prior to execution of a cell """ pass def postExecute(self): """ Callback function that is run after execution of a code """ pass def postRunCell(self): """ Callback function that is run after execution of a cell (after post-execute) """ # TODO: Do more than just update the plot, but also update _all_ the # widgets. Make a callback in plkWidget for that. QtipWindow might also # want to loop over some stuff. if self.whichWidget == 'plk': self.plkWidget.updatePlot() elif self.whichWidget == 'binary': self.binaryWidget.updatePlot()
def run(self, dock=False): # Checks if a console is open if self.status is not None: if (dock and self.status == 'docked') or (not dock and self.status == 'windowed'): if self.status == 'windowed': self.control.raise_() self.control.activateWindow() return elif self.status == 'docked': # Close current if self.dock is not None: self.dock.close() else: # Close current self.control.close() try: if QT_VERSION == 4: from IPython.qt.console.rich_ipython_widget import RichIPythonWidget else: from qtconsole.rich_ipython_widget import RichIPythonWidget from IPython.qt.inprocess import QtInProcessKernelManager from qgis import core, gui # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt%s' % (QT_VERSION if QT_VERSION != 5 else '') kernel.shell.push({ 'iface': self.iface, 'canvas': self.canvas, 'core': core, 'gui': gui, 'propertize': propertize, 'plugin_instance': self, #'app': app, }) if int(self.get_settings('propertize', DEFAULT_PROPERTIZE)): kernel.shell.ex('propertize(core)') kernel.shell.ex('propertize(gui)') # Import in the current namespace kernel.shell.ex('from PyQt%s.QtCore import *' % QT_VERSION) kernel.shell.ex('from PyQt%s.QtGui import *' % QT_VERSION) kernel.shell.ex('from qgis.core import *') kernel.shell.ex('from qgis.gui import *') kernel_client = kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() # No: this exits QGIS! #app.exit() self.status = None self.control = None self.dock = None # or RichIPythonWidget class myWidget(RichIPythonWidget): def closeEvent(self, event): stop() event.accept() def resizeEvent(self, event): super(myWidget, self).resizeEvent(event) self.console_resize() event.accept() def get_columns(self): try: font_width = QFontMetrics(self.font).width(' ') except TypeError: font_width = 10 return int(self.size().width() / font_width) def console_resize(self): self.width = self.get_columns() class myDock(QDockWidget): def closeEvent(self, event): stop() event.accept() # IPythonWidget.gui_completion : ‘plain’|’droplist’|’ncurses’ # IPythonWidget.height : Integer # IPythonWidget.width : Integer # TODO: settings # myWidget.width = 160 myWidget.gui_completion = 'plain' myWidget.paging = 'none' self.control = myWidget() self.control.kernel_manager = kernel_manager self.control.kernel_client = kernel_client self.control.exit_requested.connect(stop) if not dock: self.status = 'windowed' self.control.show() else: self.status = 'docked' self.dock = myDock() self.dock.setWidget(self.control) self.iface.addDockWidget(Qt.BottomDockWidgetArea, self.dock) # Font size regulation self.set_font() self.control._set_font(self.console_font) def shout(): from IPython.core import usage self.control._control.clear() self.control._reading = False self.control._highlighter.highlighting_on = False try: self.control._append_before_prompt_pos = self.control._get_cursor( ).position() except Exception as ex: # Can't set attribute .... on mac/win pass if int(self.get_settings('show_help', DEFAULT_SHOW_HELP)): banner = getattr(usage, 'default_banner', usage.default_gui_banner) self.control._append_html( '<small>%s</small>' % banner.replace('\n', '<br>').strip()) if int(self.get_settings('propertize', DEFAULT_PROPERTIZE)): propertize_text = ( """All returning-something and no-args <code>core</code> and <code>gui</code> <code>Qgs*</code> class members have a <code>p_*</code> equivalent property to ease class introspection with <strong>TAB</strong> completion.""" ) else: propertize_text = _tr( """Propertize has been disabled, you can re-activate it in the pugin's settings.""" ) self.control._append_html( _tr("""<br><h3>Welcome to QGIS <a href="https://ipython.org/">IPython</a> Console</h3> You have access to <code>canvas</code>, <code>iface</code>, <code>app</code> (QGIS application) objects and to all <code>qgis</code> and <code>PyQt</code> <code>core</code> and <code>gui</code> modules directly from the shell. %s Don't forget that you have access to all your underlying shell commands too!<br> <em>Enjoy IPyConsole! Another hack by <a href="http://www.itopen.it">ItOpen</a></em></br> """) % propertize_text) def monkey_patch_columnize(control): """As the name suggests... dynamic column number: stock qtconsole doesn't resize its column number on window resize but sticks to 80""" from IPython.qt.console.completion_plain import text old_columnize = text.columnize def new_columnize(items, separator=' ', displaywidth=80): displaywidth = control.get_columns() return old_columnize(items, separator, displaywidth) text.columnize = new_columnize monkey_patch_columnize(self.control) QTimer.singleShot(0, shout) except ImportError as e: QMessageBox.information( self.iface.mainWindow(), _tr(u'Error'), _tr(u'You need to install <b>IPython 3.1.0</b> or <b>Jupyter 1.0.0</b> (and then restart QGIS) before running this <b>IPyConsole</b> plugin.<br>IPython can be installed with <code>pip install "ipython[all]==3.1.0 qtconsole"</code> or (better) <code>pip install jupyter==1.0.0 qtconsole</code>. More informations about IPython installation on <a href="https://ipython.org/install.html">https://ipython.org/install.html</a>. Windows users might need to run the commands as admin in the OSGEO Command Shell.<br>The exception message is: %s' ) % e)
class BaseApp(QtCore.QObject): def __init__(self, argv): QtCore.QObject.__init__(self) self.log = get_logger_from_class(self) self.this_dir, self.this_filename = os.path.split(__file__) self.qtapp = QtWidgets.QApplication.instance() if not self.qtapp: self.qtapp = QtWidgets.QApplication(argv) self.settings = LQCollection() self.setup_console_widget() # FIXME Breaks things for microscopes, but necessary for stand alone apps! #if hasattr(self, "setup"): # self.setup() if not hasattr(self, 'name'): self.name = "ScopeFoundry" self.qtapp.setApplicationName(self.name) def exec_(self): return self.qtapp.exec_() def setup_console_widget(self): # Console if CONSOLE_TYPE == 'pyqtgraph.console': self.console_widget = pyqtgraph.console.ConsoleWidget( namespace={ 'app': self, 'pg': pg, 'np': np }, text="ScopeFoundry Console") elif CONSOLE_TYPE == 'qtconsole': # https://github.com/ipython/ipython-in-depth/blob/master/examples/Embedding/inprocess_qtconsole.py self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push({'np': np, 'app': self}) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() #self.console_widget = RichIPythonWidget() self.console_widget = RichJupyterWidget() self.console_widget.setWindowTitle("ScopeFoundry IPython Console") self.console_widget.kernel_manager = self.kernel_manager self.console_widget.kernel_client = self.kernel_client else: raise ValueError("CONSOLE_TYPE undefined") return self.console_widget def setup(self): pass def settings_save_ini(self, fname, save_ro=True): """""" config = configparser.ConfigParser() config.optionxform = str config.add_section('app') config.set('app', 'name', self.name) for lqname, lq in self.settings.as_dict().items(): if not lq.ro or save_ro: config.set('app', lqname, lq.ini_string_value()) with open(fname, 'w') as configfile: config.write(configfile) self.log.info("ini settings saved to {} {}".format( fname, config.optionxform)) def settings_load_ini(self, fname): self.log.info("ini settings loading from " + fname) config = configparser.ConfigParser() config.optionxform = str config.read(fname) if 'app' in config.sections(): for lqname, new_val in config.items('app'): #print(lqname) lq = self.settings.as_dict().get(lqname) if lq: if lq.dtype == bool: new_val = str2bool(new_val) lq.update_value(new_val) def settings_save_ini_ask(self, dir=None, save_ro=True): """Opens a Save dialogue asking the user to select a save destination and give the save file a filename. Saves settings to an .ini file.""" # TODO add default directory, etc fname, _ = QtWidgets.QFileDialog.getSaveFileName( self.ui, caption=u'Save Settings', dir=u"", filter=u"Settings (*.ini)") #print(repr(fname)) if fname: self.settings_save_ini(fname, save_ro=save_ro) return fname def settings_load_ini_ask(self, dir=None): """Opens a Load dialogue asking the user which .ini file to load into our app settings. Loads settings from an .ini file.""" # TODO add default directory, etc fname, _ = QtWidgets.QFileDialog.getOpenFileName( None, "Settings (*.ini)") #print(repr(fname)) if fname: self.settings_load_ini(fname) return fname
def getIPythonDialog(): from IPython.qt.console.rich_ipython_widget import RichIPythonWidget from IPython.qt.inprocess import QtInProcessKernelManager # from IPython.kernel.inprocess.ipkernel import InProcessKernel km = QtInProcessKernelManager() km.start_kernel() kernel = km.kernel kernel.gui = 'qt4' kernel_client = km.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() km.shutdown_kernel() class IPythonDialog(RichIPythonWidget, QVistrailsPaletteInterface): """This class incorporates an IPython shell into a dockable widget for use in the VisTrails environment""" def __init__(self, parent=None): RichIPythonWidget.__init__(self, parent) self.running_workflow = False self.kernel_manager = km self.kernel_client = kernel_client self.exit_requested.connect(stop) #locals() returns the original dictionary, not a copy as #the docs say # self.firstLocals = copy.copy(locals()) # self.shell = IPythonXXX(self.firstLocals,None) # layout = QtGui.QVBoxLayout() # layout.setMargin(0) # layout.setSpacing(0) # layout.addWidget(self.shell) # self.setLayout(layout) # self.setWidget(self.shell) self.setWindowTitle("Console") # self.setTitleBarWidget(QtGui.QLabel(self.shell.windowTitle())) # self.monitorWindowTitle(self.shell) self.vistrails_interpreter = get_default_interpreter() def visibility_changed(self, visible): QVistrailsPaletteInterface.visibility_changed(self, visible) if visible: self.show() else: self.hide() def hide(self): """suspend() -> None Called when hiding the parent window in order to recover the previous state. """ #recovering the state sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ sys.stdin = sys.__stdin__ RichIPythonWidget.hide(self) def show(self): """show() -> None Store previous state and starts capturing all interactive input and output. """ # capture all interactive input/output sys.stdout = self sys.stderr = self sys.stdin = self RichIPythonWidget.show(self) def showEvent(self, e): """showEvent(e) -> None Event handler called when the dialog acquires focus """ self.show() def flush(self): """flush() -> None. Simulate stdin, stdout, and stderr. """ pass def isatty(self): """isatty() -> int Simulate stdin, stdout, and stderr. """ return 1 def readline(self): """readline() -> str Simulate stdin, stdout, and stderr. """ return "" def write(self, text): """write(text: str) -> None Simulate stdin, stdout, and stderr. """ self.input_buffer = '' if not self.running_workflow: self.running_workflow = True # make text blue self._append_plain_text("\n\x1b[34m<STANDARD OUTPUT>\x1b[0m\n", True) self._append_plain_text(text, True) self._prompt_pos = self._get_end_cursor().position() self._control.ensureCursorVisible() self._control.moveCursor(QtGui.QTextCursor.End) def eventFilter(self, obj, event): """ Reimplemented to ensure a console-like behavior in the underlying text widgets. """ etype = event.type() if etype == QtCore.QEvent.KeyPress: self.running_workflow = False return RichIPythonWidget.eventFilter(self, obj, event) return IPythonDialog
class InProcessRunner(BaseFrontendMixin, QObject): ''' A runner object that handles running the running tool code via an in-process IPython kernel. Base off initial runipy code amended to handle in-process running and the IPython FrontendWidget. ''' # Emitted when a user visible 'execute_request' has been submitted to the # kernel from the FrontendWidget. Contains the code to be executed. executing = pyqtSignal(object) # Emitted when a user-visible 'execute_reply' has been received from the # kernel and processed by the FrontendWidget. Contains the response message. executed = pyqtSignal(object) # Emitted when an exit request has been received from the kernel. exit_requested = pyqtSignal(object) # Execute next cell execute_next = pyqtSignal() # Emit current cell number progress = pyqtSignal(object) _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos']) _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos']) _ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind']) _local_kernel = False _hidden = False MIME_MAP = { 'image/jpeg': 'jpeg', 'image/png': 'png', 'text/plain': 'text', 'text/html': 'html', 'text/latex': 'latex', 'application/javascript': 'html', 'image/svg+xml': 'svg', } #--------------------------------------------------------------------------- # 'object' interface #--------------------------------------------------------------------------- def __init__(self, *args, **kwargs): super(InProcessRunner, self).__init__(*args, **kwargs) # FrontendWidget protected variables. self._kernel_manager = None self._kernel_client = None self._request_info = { 'execute': {} } self._callback_dict = {} self._result_queue = [] self._final_msg_id = None self._cell_execute_ids = {} self.is_active = False self.status = STATUS_READY self._executing = False # Set flag for whether we are connected via localhost. self._local_kernel = kwargs.get('local_kernel', InProcessRunner._local_kernel) self.kernel_manager = KernelManager() self.kernel_manager.start_kernel() self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() def __del__(self): if self.kernel_client: self.kernel_client.stop_channels() if self.kernel_manager: self.kernel_manager.shutdown_kernel() def run(self, tool, varsi, progress_callback=None, result_callback=None): ''' Run all the cells of a notebook in order and update the outputs in-place. ''' self.is_active = True self.varsi = varsi self._progress_callback = progress_callback self._result_callback = result_callback self._result_queue = [] # Cache for unhandled messages self._cell_execute_ids = {} self._execute_start = datetime.now() self._execute('%reset_selective -f [^_]') self.kernel_manager.kernel.shell.push({'varsi': varsi}) self._execute(r'''from pathomx.kernel_helpers import pathomx_notebook_start, pathomx_notebook_stop, progress, open_with_progress pathomx_notebook_start(varsi, vars());''') setup_languages(self._execute, tool.language) msg_id = self._execute(tool.code) self._cell_execute_ids[msg_id] = (tool.code, 1, 100) # Store cell and progress self._final_msg_id = self._execute(r'''pathomx_notebook_stop(vars());''') def run_completed(self, error=False, traceback=None): logging.info("Notebook run took %s" % (datetime.now() - self._execute_start)) result = {} if error: result['status'] = -1 result['traceback'] = traceback else: # Apply unhandled results for msg in self._result_queue: self._handle_execute_result(msg) result['status'] = 0 # Return input; temp result['varso'] = self.kernel_manager.kernel.shell.user_ns['varso'] self.is_active = False if self._result_callback: self._result_callback(result) def _execute(self, source): """ Execute 'source'. If 'hidden', do not show any output. See parent class :meth:`execute` docstring for full details. """ msg_id = self.kernel_client.execute(source, True) self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'user') return msg_id #--------------------------------------------------------------------------- # 'BaseFrontendMixin' abstract interface #--------------------------------------------------------------------------- def _handle_clear_output(self, msg): """Handle clear output messages.""" if not self._hidden and self._is_from_this_session(msg): wait = msg['content'].get('wait', True) if wait: self._pending_clearoutput = True else: self.clear_output() def _handle_execute_reply(self, msg): """ Handles replies for code execution. """ logging.debug("execute: %s", msg.get('content', '')) msg_id = msg['parent_header']['msg_id'] if msg_id == self._final_msg_id: return self.run_completed() if msg_id not in self._cell_execute_ids: return (self._current_cell, n, pc) = self._cell_execute_ids[msg_id] logging.info("Execute cell %d complete in %s" % (n, datetime.now() - self._execute_start)) #self.progress.emit( pc ) if self._progress_callback: self._progress_callback(pc) info = self._request_info['execute'].get(msg_id) # unset reading flag, because if execute finished, raw_input can't # still be pending. self._reading = False if info and info.kind == 'user' and not self._hidden: # Make sure that all output from the SUB channel has been processed # before writing a new prompt. self.kernel_client.iopub_channel.flush() content = msg['content'] status = content['status'] if status == 'ok': self._process_execute_ok(msg) self.execute_next.emit() elif status == 'error': self._process_execute_error(msg) elif status == 'aborted': self._process_execute_abort(msg) self.executed.emit(msg) self._request_info['execute'].pop(msg_id) elif info and info.kind == 'silent_exec_callback' and not self._hidden: self._handle_exec_callback(msg) self._request_info['execute'].pop(msg_id) else: super(FrontendWidget, self)._handle_execute_reply(msg) def _process_execute_abort(self, msg): """ Process a reply for an aborted execution request. """ logging.error("ERROR: execution aborted\n") def _process_execute_error(self, msg): """ Process a reply for an execution request that resulted in an error. """ content = msg['content'] # If a SystemExit is passed along, this means exit() was called - also # all the ipython %exit magic syntax of '-k' to be used to keep # the kernel running if content['ename'] == 'SystemExit': keepkernel = content['evalue'] == '-k' or content['evalue'] == 'True' self._keep_kernel_on_exit = keepkernel self.exit_requested.emit(self) else: traceback = '\n'.join(content['traceback']) self.run_completed(error=True, traceback=traceback) def _process_execute_ok(self, msg): """ Process a reply for a successful execution request. """ pass def _handle_kernel_died(self, since_last_heartbeat): """Handle the kernel's death (if we do not own the kernel). """ logging.warn("kernel died") self.reset() def _handle_kernel_info_reply(self, *args, **kwargs): pass def _handle_kernel_restarted(self, died=True): """Notice that the autorestarter restarted the kernel. There's nothing to do but show a message. """ logging.warn("kernel restarted") self.reset() def _handle_execute_result(self, msg): """ Handle display hook output. """ logging.debug("execute_result: %s", msg.get('content', '')) if not self._hidden and self._is_from_this_session(msg): msg_id = msg['parent_header']['msg_id'] if msg_id not in self._cell_execute_ids: # Only on the in-process kernel can this happen self._result_queue.append(msg) return (cell, n, pc) = self._cell_execute_ids[msg_id] #out = NotebookNode(output_type='display_data') for mime, data in msg['content']['data'].items(): try: attr = self.MIME_MAP[mime] except KeyError: raise NotImplementedError('unhandled mime type: %s' % mime) #setattr(out, attr, data) #cell['outputs'].append(out) def _handle_stream(self, msg): """ Handle stdout, stderr, and stdin. """ logging.debug("stream: %s", msg.get('content', '')) if not self._hidden and self._is_from_this_session(msg): logging.info(msg['content']['data']) def _handle_shutdown_reply(self, msg): """ Handle shutdown signal, only if from other console. """ logging.info("shutdown: %s", msg.get('content', '')) restart = msg.get('content', {}).get('restart', False) if not self._hidden and not self._is_from_this_session(msg): # got shutdown reply, request came from session other than ours if restart: # someone restarted the kernel, handle it self._handle_kernel_restarted(died=False) else: # kernel was shutdown permanently self.exit_requested.emit(self) def _handle_status(self, msg): """Handle status message""" # This is where a busy/idle indicator would be triggered, # when we make one. state = msg['content'].get('execution_state', '') if state == 'starting': # kernel started while we were running if self._executing: self._handle_kernel_restarted(died=True) elif state == 'idle': pass elif state == 'busy': pass #--------------------------------------------------------------------------- # 'FrontendWidget' public interface #--------------------------------------------------------------------------- def interrupt_kernel(self): """ Attempts to interrupt the running kernel. Also unsets _reading flag, to avoid runtime errors if raw_input is called again. """ self._reading = False self.kernel_manager.interrupt_kernel() def restart_kernel(self, message, now=False): """ Attempts to restart the running kernel. """ # Pause the heart beat channel to prevent further warnings. self.kernel_client.hb_channel.pause() try: self.kernel_manager.restart_kernel(now=now) except RuntimeError as e: logging.error('Error restarting kernel: %s\n' % e) else: logging.info("Restarting kernel...\n")
def console(client, args): local = { 'client': client, 'auth': client.auth, 'reset': client.reset, 'config': client.config, 'execute': client.execute, } if args['scriptName']: ############################################################# # EXECUTE FILE # ############################################################# sys.argv = [] sys.argv.append(args['scriptName']) sys.argv.extend(args['scriptArgs']) try: f = open(sys.argv[0]) source_code = f.read() f.close() except IOError as e: raise pyAMI.exception.Error(e) compiled_code = compile(source_code, sys.argv[0], 'exec') safe_exec(compiled_code, globals(), local) ############################################################# else: ############################################################# # RUN CONSOLE # ############################################################# sys.argv = [sys.argv[0]] ############################################################# banner = pyAMI.config.banner if args['nosplash'] == False else '' ############################################################# if args['gIPython']: ##################################################### # IPYTHON GRAPHICAL MODE # ##################################################### try: from IPython.qt.console.rich_ipython_widget import RichIPythonWidget from IPython.qt.inprocess import QtInProcessKernelManager from IPython.lib import guisupport except ImportError as e: raise pyAMI.exception.Error('module `IPython` not properly installed: %s' % e) ################################ # HACK IPYTHON BANNER # ################################ RichIPythonWidget._banner_default = lambda self: banner ################################ # KERNEL_MANAGER # ################################ kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() ################################ # KERNEL_CLIENT # ################################ kernel_client = kernel_manager.client() kernel_client.start_channels() ################################ # PYAMI # ################################ kernel_manager.kernel.shell.push(local) ################################ # APPLICATION # ################################ a = guisupport.get_app_qt4() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() a.exit() control = RichIPythonWidget() control.kernel_manager = kernel_manager control.kernel_client = kernel_client control.exit_requested.connect(stop) control.show() guisupport.start_event_loop_qt4(a) ##################################################### elif args['cIPython']: ##################################################### # IPYTHON CONSOLE MODE # ##################################################### try: from IPython.terminal.embed import InteractiveShellEmbed except ImportError as e: raise pyAMI.exception.Error('module `IPython` not properly installed: %s' % e) ################################ # SHELL # ################################ shell = InteractiveShellEmbed(banner1 = banner, banner2 = None) shell(local_ns = local) ##################################################### else: ##################################################### # DEFAULT MODE # ##################################################### code.interact(banner = banner, local = local) ##################################################### return 0
import sys from IPython.qt.console.rich_ipython_widget import RichIPythonWidget from IPython.qt.inprocess import QtInProcessKernelManager from IPython.lib import guisupport from PyQt4.QtGui import QApplication app = QApplication(sys.argv) kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() # here you should exit your application with a suitable call sys.exit() widget = RichIPythonWidget() widget.kernel_manager = kernel_manager widget.kernel_client = kernel_client widget.exit_requested.connect(stop) widget.setWindowTitle("IPython shell")
class NotebookRunner(BaseFrontendMixin, QObject): ''' A runner object that handles running the running of IPython notebook and working responses back into the output notebook. Based off the original runipy code amended to handle in-process running and the IPython FrontendWidget. ''' # Emitted when a user visible 'execute_request' has been submitted to the # kernel from the FrontendWidget. Contains the code to be executed. executing = pyqtSignal(object) # Emitted when a user-visible 'execute_reply' has been received from the # kernel and processed by the FrontendWidget. Contains the response message. executed = pyqtSignal(object) # Emitted when an exit request has been received from the kernel. exit_requested = pyqtSignal(object) # Execute next cell execute_next = pyqtSignal() # Emitted when all cells a notebook have been run notebook_completed = pyqtSignal() notebook_result = pyqtSignal(object) # Emit current cell number progress = pyqtSignal(object) _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos']) _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos']) _ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind']) _local_kernel = False _hidden = False MIME_MAP = { 'image/jpeg': 'jpeg', 'image/png': 'png', 'text/plain': 'text', 'text/html': 'html', 'text/latex': 'latex', 'application/javascript': 'html', 'image/svg+xml': 'svg', } #--------------------------------------------------------------------------- # 'object' interface #--------------------------------------------------------------------------- def __init__(self, *args, **kwargs): super(NotebookRunner, self).__init__(*args, **kwargs) # FrontendWidget protected variables. self._kernel_manager = None self._kernel_client = None self._request_info = {} self._request_info['execute'] = {} self._callback_dict = {} self._result_queue = [] self._final_msg_id = None self._cell_execute_ids = {} self._is_active = False self._executing = False # Set flag for whether we are connected via localhost. self._local_kernel = kwargs.get('local_kernel', NotebookRunner._local_kernel) self.kernel_manager = KernelManager() self.kernel_manager.start_kernel() self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels(stdin=False, hb=False) def __del__(self): if self.kernel_client: self.kernel_client.stop_channels() if self.kernel_manager: self.kernel_manager.shutdown_kernel() def iter_code_cells(self): ''' Iterate over the notebook cells containing code. ''' for ws in self.nb.worksheets: for cell in ws.cells: if cell.cell_type == 'code': yield cell def count_code_cells(self): ''' Return the number of code cells in the notebook ''' for n, cell in enumerate(self.iter_code_cells()): pass return n + 1 def run_notebook(self, notebook, varsi, progress_callback=None, result_callback=None): ''' Run all the cells of a notebook in order and update the outputs in-place. ''' self.nb = notebook self.varsi = varsi # Pickle all variables and import to the notebook (depickler) with open(self.varsi['_pathomx_pickle_in'], 'wb') as f: pickle.dump(self.varsi, f, -1) # Highest protocol for speed self._progress_callback = progress_callback self._result_callback = result_callback self._notebook_generator = self.iter_code_cells() self._total_code_cell_number = self.count_code_cells() self._is_active = True self._result_queue = [] # Cache for unhandled messages self._cell_execute_ids = {} self._execute_start = datetime.now() msg_id = self._execute('''%%reset -f from pathomx import pathomx_notebook_start, pathomx_notebook_stop pathomx_notebook_start('%s', vars());''' % (self.varsi['_pathomx_pickle_in'])) logging.debug("Runing notebook; startup message: %s" % msg_id) for n, cell in enumerate(self.iter_code_cells()): msg_id = self._execute(cell.input) logging.debug('Cell number %d; %s' % (n, msg_id)) progress = n / float(self._total_code_cell_number) self._cell_execute_ids[msg_id] = (cell, n + 1, progress ) # Store cell and progress self._final_msg_id = self._execute( '''pathomx_notebook_stop('%s', vars());''' % (self.varsi['_pathomx_pickle_out'])) logging.debug("Runing notebook; shutdown message: %s" % self._final_msg_id) def run_notebook_completed(self, error=False, traceback=None): logging.info("Notebook run took %s" % (datetime.now() - self._execute_start)) result = {} if error: result['status'] = -1 result['traceback'] = traceback else: # Apply unhandled results for msg in self._result_queue: self._handle_execute_result(msg) result['status'] = 0 # Return input; temp with open(self.varsi['_pathomx_pickle_out'], 'rb') as f: result['varso'] = pickle.load(f) result['notebook'] = self.nb self._is_active = False self.notebook_completed.emit() self.notebook_result.emit(result) if self._result_callback: self._result_callback(result) def _execute(self, source, hidden=False): """ Execute 'source'. If 'hidden', do not show any output. See parent class :meth:`execute` docstring for full details. """ msg_id = self.kernel_client.execute(source, hidden) self._request_info['execute'][msg_id] = self._ExecutionRequest( msg_id, 'user') self._hidden = hidden #if not hidden: # self.executing.emit(source) return msg_id #--------------------------------------------------------------------------- # 'BaseFrontendMixin' abstract interface #--------------------------------------------------------------------------- def _handle_clear_output(self, msg): """Handle clear output messages.""" if not self._hidden and self._is_from_this_session(msg): wait = msg['content'].get('wait', True) if wait: self._pending_clearoutput = True else: self.clear_output() def _handle_execute_reply(self, msg): """ Handles replies for code execution. """ logging.debug("execute: %s", msg.get('content', '')) msg_id = msg['parent_header']['msg_id'] if msg_id == self._final_msg_id: return self.run_notebook_completed() if msg_id not in self._cell_execute_ids: return (self._current_cell, n, pc) = self._cell_execute_ids[msg_id] logging.info("Execute cell %d complete in %s" % (n, datetime.now() - self._execute_start)) self.progress.emit(pc) if self._progress_callback: self._progress_callback(pc) info = self._request_info['execute'].get(msg_id) # unset reading flag, because if execute finished, raw_input can't # still be pending. self._reading = False if info and info.kind == 'user' and not self._hidden: # Make sure that all output from the SUB channel has been processed # before writing a new prompt. self.kernel_client.iopub_channel.flush() # Reset the ANSI style information to prevent bad text in stdout # from messing up our colors. We're not a true terminal so we're # allowed to do this. # if self.ansi_codes: # self._ansi_processor.reset_sgr() content = msg['content'] status = content['status'] if status == 'ok': self._process_execute_ok(msg) self.execute_next.emit() elif status == 'error': self._process_execute_error(msg) elif status == 'aborted': self._process_execute_abort(msg) self.executed.emit(msg) self._request_info['execute'].pop(msg_id) elif info and info.kind == 'silent_exec_callback' and not self._hidden: self._handle_exec_callback(msg) self._request_info['execute'].pop(msg_id) else: super(FrontendWidget, self)._handle_execute_reply(msg) def _process_execute_abort(self, msg): """ Process a reply for an aborted execution request. """ logging.error("ERROR: execution aborted\n") def _process_execute_error(self, msg): """ Process a reply for an execution request that resulted in an error. """ content = msg['content'] # If a SystemExit is passed along, this means exit() was called - also # all the ipython %exit magic syntax of '-k' to be used to keep # the kernel running if content['ename'] == 'SystemExit': keepkernel = content['evalue'] == '-k' or content[ 'evalue'] == 'True' self._keep_kernel_on_exit = keepkernel self.exit_requested.emit(self) else: traceback = ''.join(content['traceback']) logging.info(traceback) out = NotebookNode(output_type='pyerr') out.ename = content['ename'] out.evalue = content['evalue'] out.traceback = content['traceback'] self._current_cell['outputs'].append(out) self.run_notebook_completed(error=True, traceback=content['traceback']) def _process_execute_ok(self, msg): """ Process a reply for a successful execution request. """ payload = msg['content']['payload'] for item in payload: if not self._process_execute_payload(item): warning = 'Warning: received unknown payload of type %s' print(warning % repr(item['source'])) content = msg['content'] msg_type = msg['msg_type'] # IPython 3.0.0-dev writes pyerr/pyout in the notebook format but uses # error/execute_result in the message spec. This does the translation # needed for tests to pass with IPython 3.0.0-dev notebook3_format_conversions = { 'error': 'pyerr', 'execute_result': 'pyout' } msg_type = notebook3_format_conversions.get(msg_type, msg_type) out = NotebookNode(output_type=msg_type) if 'execution_count' in content: self._current_cell['prompt_number'] = content['execution_count'] out.prompt_number = content['execution_count'] if msg_type in ('status', 'pyin', 'execute_input'): return elif msg_type == 'stream': out.stream = content['name'] out.text = content['data'] elif msg_type in ('display_data', 'pyout'): # Is this handled in _handle_execute_result? for mime, data in content['data'].items(): try: attr = self.MIME_MAP[mime] except KeyError: raise NotImplementedError('unhandled mime type: %s' % mime) setattr(out, attr, data) return elif msg_type == 'pyerr': # Is this handled in _handle_execute_errror? out.ename = content['ename'] out.evalue = content['evalue'] out.traceback = content['traceback'] return elif msg_type == 'clear_output': self._current_cell['outputs'] = [] return elif msg_type == 'execute_reply': pass else: raise NotImplementedError('unhandled iopub message: %s' % msg_type) self._current_cell['outputs'].append(out) def _handle_kernel_died(self, since_last_heartbeat): """Handle the kernel's death (if we do not own the kernel). """ logging.warn("kernel died") self.reset() def _handle_kernel_restarted(self, died=True): """Notice that the autorestarter restarted the kernel. There's nothing to do but show a message. """ logging.warn("kernel restarted") self.reset() def _handle_execute_result(self, msg): """ Handle display hook output. """ logging.debug("execute_result: %s", msg.get('content', '')) if not self._hidden and self._is_from_this_session(msg): msg_id = msg['parent_header']['msg_id'] if msg_id not in self._cell_execute_ids: # Only on the in-process kernel can this happen self._result_queue.append(msg) return (cell, n, pc) = self._cell_execute_ids[msg_id] out = NotebookNode(output_type='display_data') for mime, data in msg['content']['data'].items(): try: attr = self.MIME_MAP[mime] except KeyError: raise NotImplementedError('unhandled mime type: %s' % mime) setattr(out, attr, data) cell['outputs'].append(out) def _handle_stream(self, msg): """ Handle stdout, stderr, and stdin. """ logging.debug("stream: %s", msg.get('content', '')) if not self._hidden and self._is_from_this_session(msg): logging.info(msg['content']['data']) def _handle_shutdown_reply(self, msg): """ Handle shutdown signal, only if from other console. """ logging.info("shutdown: %s", msg.get('content', '')) restart = msg.get('content', {}).get('restart', False) if not self._hidden and not self._is_from_this_session(msg): # got shutdown reply, request came from session other than ours if restart: # someone restarted the kernel, handle it self._handle_kernel_restarted(died=False) else: # kernel was shutdown permanently self.exit_requested.emit(self) def _handle_status(self, msg): """Handle status message""" # This is where a busy/idle indicator would be triggered, # when we make one. state = msg['content'].get('execution_state', '') if state == 'starting': # kernel started while we were running if self._executing: self._handle_kernel_restarted(died=True) elif state == 'idle': pass elif state == 'busy': pass #--------------------------------------------------------------------------- # 'FrontendWidget' public interface #--------------------------------------------------------------------------- def interrupt_kernel(self): """ Attempts to interrupt the running kernel. Also unsets _reading flag, to avoid runtime errors if raw_input is called again. """ self._reading = False self.kernel_manager.interrupt_kernel() def restart_kernel(self, message, now=False): """ Attempts to restart the running kernel. """ # Pause the heart beat channel to prevent further warnings. self.kernel_client.hb_channel.pause() try: self.kernel_manager.restart_kernel(now=now) except RuntimeError as e: logging.error('Error restarting kernel: %s\n' % e) else: logging.info("Restarting kernel...\n")
class InProcessRunner(BaseFrontendMixin, QObject): ''' A runner object that handles running the running tool code via an in-process IPython kernel. Base off initial runipy code amended to handle in-process running and the IPython FrontendWidget. ''' # Emitted when a user visible 'execute_request' has been submitted to the # kernel from the FrontendWidget. Contains the code to be executed. executing = pyqtSignal(object) # Emitted when a user-visible 'execute_reply' has been received from the # kernel and processed by the FrontendWidget. Contains the response message. executed = pyqtSignal(object) # Emitted when an exit request has been received from the kernel. exit_requested = pyqtSignal(object) # Execute next cell execute_next = pyqtSignal() # Emit current cell number progress = pyqtSignal(object) _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos']) _CompletionRequest = namedtuple('_CompletionRequest', ['id', 'pos']) _ExecutionRequest = namedtuple('_ExecutionRequest', ['id', 'kind']) _local_kernel = False _hidden = False MIME_MAP = { 'image/jpeg': 'jpeg', 'image/png': 'png', 'text/plain': 'text', 'text/html': 'html', 'text/latex': 'latex', 'application/javascript': 'html', 'image/svg+xml': 'svg', } #--------------------------------------------------------------------------- # 'object' interface #--------------------------------------------------------------------------- def __init__(self, *args, **kwargs): super(InProcessRunner, self).__init__(*args, **kwargs) # FrontendWidget protected variables. self._kernel_manager = None self._kernel_client = None self._request_info = {'execute': {}} self._callback_dict = {} self._result_queue = [] self._final_msg_id = None self._cell_execute_ids = {} self.is_active = False self.status = STATUS_READY self._executing = False # Set flag for whether we are connected via localhost. self._local_kernel = kwargs.get('local_kernel', InProcessRunner._local_kernel) self.kernel_manager = KernelManager() self.kernel_manager.start_kernel() self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() def __del__(self): if self.kernel_client: self.kernel_client.stop_channels() if self.kernel_manager: self.kernel_manager.shutdown_kernel() def run(self, tool, varsi, progress_callback=None, result_callback=None): ''' Run all the cells of a notebook in order and update the outputs in-place. ''' self.is_active = True self.varsi = varsi self._progress_callback = progress_callback self._result_callback = result_callback self._result_queue = [] # Cache for unhandled messages self._cell_execute_ids = {} self._execute_start = datetime.now() self._execute('%reset_selective -f [^_]') self.kernel_manager.kernel.shell.push({'varsi': varsi}) self._execute( r'''from pathomx.kernel_helpers import pathomx_notebook_start, pathomx_notebook_stop, progress, open_with_progress pathomx_notebook_start(varsi, vars());''') setup_languages(self._execute, tool.language) msg_id = self._execute(tool.code) self._cell_execute_ids[msg_id] = (tool.code, 1, 100 ) # Store cell and progress self._final_msg_id = self._execute( r'''pathomx_notebook_stop(vars());''') def run_completed(self, error=False, traceback=None): logging.info("Notebook run took %s" % (datetime.now() - self._execute_start)) result = {} if error: result['status'] = -1 result['traceback'] = traceback else: # Apply unhandled results for msg in self._result_queue: self._handle_execute_result(msg) result['status'] = 0 # Return input; temp result['varso'] = self.kernel_manager.kernel.shell.user_ns['varso'] self.is_active = False if self._result_callback: self._result_callback(result) def _execute(self, source): """ Execute 'source'. If 'hidden', do not show any output. See parent class :meth:`execute` docstring for full details. """ msg_id = self.kernel_client.execute(source, True) self._request_info['execute'][msg_id] = self._ExecutionRequest( msg_id, 'user') return msg_id #--------------------------------------------------------------------------- # 'BaseFrontendMixin' abstract interface #--------------------------------------------------------------------------- def _handle_clear_output(self, msg): """Handle clear output messages.""" if not self._hidden: # and self._is_from_this_session(msg): wait = msg['content'].get('wait', True) if wait: self._pending_clearoutput = True else: self.clear_output() def _handle_execute_reply(self, msg): """ Handles replies for code execution. """ logging.debug("execute: %s", msg.get('content', '')) msg_id = msg['parent_header']['msg_id'] if msg_id == self._final_msg_id: return self.run_completed() if msg_id not in self._cell_execute_ids: return (self._current_cell, n, pc) = self._cell_execute_ids[msg_id] logging.info("Execute cell %d complete in %s" % (n, datetime.now() - self._execute_start)) #self.progress.emit( pc ) if self._progress_callback: self._progress_callback(pc) info = self._request_info['execute'].get(msg_id) # unset reading flag, because if execute finished, raw_input can't # still be pending. self._reading = False if info and info.kind == 'user' and not self._hidden: # Make sure that all output from the SUB channel has been processed # before writing a new prompt. self.kernel_client.iopub_channel.flush() content = msg['content'] status = content['status'] if status == 'ok': self._process_execute_ok(msg) self.execute_next.emit() elif status == 'error': self._process_execute_error(msg) elif status == 'aborted': self._process_execute_abort(msg) self.executed.emit(msg) self._request_info['execute'].pop(msg_id) elif info and info.kind == 'silent_exec_callback' and not self._hidden: self._handle_exec_callback(msg) self._request_info['execute'].pop(msg_id) else: super(FrontendWidget, self)._handle_execute_reply(msg) def _process_execute_abort(self, msg): """ Process a reply for an aborted execution request. """ logging.error("ERROR: execution aborted\n") def _process_execute_error(self, msg): """ Process a reply for an execution request that resulted in an error. """ content = msg['content'] # If a SystemExit is passed along, this means exit() was called - also # all the ipython %exit magic syntax of '-k' to be used to keep # the kernel running if content['ename'] == 'SystemExit': keepkernel = content['evalue'] == '-k' or content[ 'evalue'] == 'True' self._keep_kernel_on_exit = keepkernel self.exit_requested.emit(self) else: traceback = '\n'.join(content['traceback']) self.run_completed(error=True, traceback=traceback) def _process_execute_ok(self, msg): """ Process a reply for a successful execution request. """ pass def _handle_kernel_died(self, since_last_heartbeat): """Handle the kernel's death (if we do not own the kernel). """ logging.warn("kernel died") self.reset() def _handle_kernel_info_reply(self, *args, **kwargs): pass def _handle_kernel_restarted(self, died=True): """Notice that the autorestarter restarted the kernel. There's nothing to do but show a message. """ logging.warn("kernel restarted") self.reset() def _handle_execute_result(self, msg): """ Handle display hook output. """ logging.debug("execute_result: %s", msg.get('content', '')) if not self._hidden: # and self._is_from_this_session(msg): msg_id = msg['parent_header']['msg_id'] if msg_id not in self._cell_execute_ids: # Only on the in-process kernel can this happen self._result_queue.append(msg) return (cell, n, pc) = self._cell_execute_ids[msg_id] #out = NotebookNode(output_type='display_data') for mime, data in msg['content']['data'].items(): try: attr = self.MIME_MAP[mime] except KeyError: raise NotImplementedError('unhandled mime type: %s' % mime) #setattr(out, attr, data) #cell['outputs'].append(out) def _handle_stream(self, msg): """ Handle stdout, stderr, and stdin. """ logging.debug("stream: %s", msg.get('content', '')) if not self._hidden: # and self._is_from_this_session(msg): logging.info(msg['content']['text']) def _handle_shutdown_reply(self, msg): """ Handle shutdown signal, only if from other console. """ logging.info("shutdown: %s", msg.get('content', '')) restart = msg.get('content', {}).get('restart', False) if not self._hidden: # and not self._is_from_this_session(msg): # got shutdown reply, request came from session other than ours if restart: # someone restarted the kernel, handle it self._handle_kernel_restarted(died=False) else: # kernel was shutdown permanently self.exit_requested.emit(self) def _handle_status(self, msg): """Handle status message""" # This is where a busy/idle indicator would be triggered, # when we make one. state = msg['content'].get('execution_state', '') if state == 'starting': # kernel started while we were running if self._executing: self._handle_kernel_restarted(died=True) elif state == 'idle': pass elif state == 'busy': pass #--------------------------------------------------------------------------- # 'FrontendWidget' public interface #--------------------------------------------------------------------------- def interrupt_kernel(self): """ Attempts to interrupt the running kernel. Also unsets _reading flag, to avoid runtime errors if raw_input is called again. """ self._reading = False self.kernel_manager.interrupt_kernel() def restart_kernel(self, message, now=False): """ Attempts to restart the running kernel. """ # Pause the heart beat channel to prevent further warnings. self.kernel_client.hb_channel.pause() try: self.kernel_manager.restart_kernel(now=now) except RuntimeError as e: logging.error('Error restarting kernel: %s\n' % e) else: logging.info("Restarting kernel...\n")