Example #1
0
	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)
Example #2
0
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
Example #4
0
    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
Example #5
0
 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)
Example #6
0
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)
Example #8
0
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 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 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_())
Example #11
0
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)
Example #12
0
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)
Example #13
0
    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)
Example #14
0
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)
Example #15
0
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)
Example #16
0
    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
Example #17
0
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()
Example #18
0
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
Example #20
0
    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
Example #21
0
 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()
Example #24
0
    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)
Example #25
0
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
Example #26
0
File: main.py Project: lind9/hexrd
    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)
Example #27
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,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)
Example #29
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)
Example #30
0
    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)
Example #32
0
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)
Example #36
0
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)
Example #37
0
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)
Example #38
0
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)
Example #39
0
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
Example #40
0
    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)
Example #41
0
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")
Example #42
0
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
Example #43
0
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_()
Example #44
0
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()
Example #45
0
    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)
Example #46
0
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
Example #47
0
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
Example #48
0
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")
Example #49
0
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
Example #50
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")
Example #51
0
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")
Example #52
0
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")