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 = QtAsyncInProcessKernelManager()
    kernel_manager.start_kernel()
    kernel = kernel_manager.kernel
    kernel.gui = 'qt4'
    kernel.shell.push({'foo': 43, 'print_process_id': print_process_id})

    kernel_client = kernel_manager.client()
    kernel_client.start_channels()

    def stop():
        kernel_client.stop_channels()
        kernel_manager.shutdown_kernel()
        app.exit()

    control = RichIPythonWidget()
    control.kernel_manager = kernel_manager
    control.kernel_client = kernel_client
    control.exit_requested.connect(stop)
    control.show()

    guisupport.start_event_loop_qt4(app)
def 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)
Exemple #3
0
def embed_shell_widget( parent_ptr ):
    '''
    Create a RichIPythonWidget as a child of the given parent QWidget.

    Parent is assumed to be an integer and is wrapped into a QWidget using sip.

    This function may only be called when init_embedded_python() previously
    returned True.  It may throw an ImportError if sip or PyQt4 is missing.
    If it successfully returns, the widget was successfully embedded.
    '''
    global _kmgr, _kclient, widget
    if( _kmgr is None ):
        raise RuntimeError( "Kernel manager not initialized!" )
    #print "embedding interactive python widget", parent_ptr, type(parent_ptr)
    import IPython
    from IPython.lib import guisupport
    if IPython.version_info[0] < 4:
        from IPython.qt.console.rich_ipython_widget import RichIPythonWidget as RichWidget
    else:
        from qtconsole.rich_jupyter_widget import RichJupyterWidget as RichWidget
    import sip
    from PyQt4 import QtGui, QtCore

    # Wave the magic wand and turn an integer into a QWidget object.
    parent = sip.wrapinstance(parent_ptr, QtGui.QWidget)

    widget = RichWidget(parent=parent, local_kernel=True)
    widget.kernel_manager = _kmgr
    widget.kernel_client = _kclient
    parent.layout().addWidget(widget)
    widget.change_font_size(-2)
    import __main__
    __main__.ipw = widget
    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)
Exemple #5
0
    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)
Exemple #6
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)
Exemple #7
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)
Exemple #8
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)
Exemple #9
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)
Exemple #10
0
     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)
Exemple #11
0
 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 __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 __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 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 create_widget(self):
        """ Create the underlying widget.

        """
        self.widget = QFrame(self.parent_widget())
        self.ipy_widget = RichIPythonWidget()
        assert self.page_control is not None  # always use paging
Exemple #16
0
    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)
Exemple #17
0
    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
Exemple #18
0
 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 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)
Exemple #20
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)
Exemple #21
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
Exemple #22
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)
Exemple #23
0
     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 __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)
Exemple #25
0
    def __init__(self, parent=None):
        super(ConsoleDockWidget, self).__init__(parent)
        self.setWindowTitle("Console")

        self.setAllowedAreas(QtCore.Qt.BottomDockWidgetArea)

        self.wgt_console = RichIPythonWidget()

        self.add_widget(self.wgt_console)

        self.setVisible(False)
Exemple #26
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)
Exemple #27
0
def shell(kernel_manager, kernel_client):
    widget = RichIPythonWidget()
    widget.kernel_manager = kernel_manager
    widget.kernel_client = kernel_client
    widget.exit_requested.connect(stop)
    widget.setWindowTitle("IPython shell")
    return widget
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_())
Exemple #29
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)
Exemple #30
0
    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)
Exemple #31
0
    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
class INinjaConsole(plugin.Plugin):
    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 _add_project(self, project_path):
        self.ipython_console.execute("import sys; sys.path += ['%s']" %
                                    project_path)

    def _del_project(self, project_path):
        """This is ugly, but I was in a hurry and copied form console
        widget"""
        self.ipython_console.execute("import sys; "
            "sys.path = [path for path in sys.path "
            "if path != '%s']" % project_path)

    def finish(self):
        # Shutdown your plugin
        pass

    def get_preferences_widget(self):
        # Return a widget for customize your plugin
        pass
Exemple #33
0
    def _createConsoleWidget(self):
        if is_using_pyqt5():
            layout = QtWidgets.QVBoxLayout()
        else:
            layout = QtGui.QVBoxLayout()
        connection_file = find_connection_file(self.connection_file)
        self.kernel_manager = QtKernelManager(connection_file=connection_file)
        self.kernel_manager.load_connection_file()
        self.kernel_manager.client_factory = QtKernelClient
        self.kernel_client = self.kernel_manager.client()
        self.kernel_client.start_channels()

        self.ipython_widget = RichIPythonWidget(self.parent)
        self.ipython_widget.kernel_manager = self.kernel_manager
        self.ipython_widget.kernel_client = self.kernel_client
        layout.addWidget(self.ipython_widget)

        return layout
class INinjaConsole(plugin.Plugin):
    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 _add_project(self, project_path):
        self.ipython_console.execute("import sys; sys.path += ['%s']" %
                                     project_path)

    def _del_project(self, project_path):
        """This is ugly, but I was in a hurry and copied form console
        widget"""
        self.ipython_console.execute("import sys; "
                                     "sys.path = [path for path in sys.path "
                                     "if path != '%s']" % project_path)

    def finish(self):
        # Shutdown your plugin
        pass

    def get_preferences_widget(self):
        # Return a widget for customize your plugin
        pass
Exemple #35
0
    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()

        #Avoid setting up multiple consoles
        alreadysetup = False
        if hasattr(self, 'console_widget'):
            if (isinstance(self.console_widget, RichJupyterWidget)):
                alreadysetup = True

        if not alreadysetup: 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
Exemple #36
0
    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)
Exemple #37
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)
Exemple #38
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
Exemple #39
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)
Exemple #40
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
Exemple #41
0
 def __new__(self, interpreter=None, message="", log="", parent=None):
     obj = RichIPythonWidget()
     obj.__class__ = ShellWidget
     return obj
Exemple #42
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
Exemple #43
0
    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
Exemple #44
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)
Exemple #45
0
 def __new__(self, interpreter=None, message="", log='', parent=None):
     obj = RichIPythonWidget()
     obj.__class__ = ShellWidget
     return obj
Exemple #46
0
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")

ipython_widget = widget
ipython_widget.show()

app.exec_()
sys.exit()
Exemple #47
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()
Exemple #48
0
class ipython_console(base_console, QtGui.QWidget):

	"""
	desc:
		An IPython-based debug window.
	"""

	def __init__(self, main_window):

		"""
		desc:
			Constructor.

		arguments:
			main_window:	The main window object.
		"""

		super(ipython_console, self).__init__(main_window)
		kernel_manager = QtInProcessKernelManager()
		kernel_manager.start_kernel()
		self.kernel = kernel_manager.kernel
		self.kernel.gui = 'qt4'
		self.kernel.shell.banner1 = ''
		kernel_client = kernel_manager.client()
		kernel_client.start_channels()
		self.control = RichIPythonWidget()
		self.control.banner = self.banner()
		self.control.kernel_manager = kernel_manager
		self.control.kernel_client = kernel_client
		self.verticalLayout = QtGui.QVBoxLayout(self)
		self.verticalLayout.setContentsMargins(0,0,0,0)
		self.setLayout(self.verticalLayout)
		self.verticalLayout.addWidget(self.control)

	def clear(self):

		"""See base_console."""

		self.control.reset(clear=True)

	def focus(self):

		"""See base_console."""

		self.control._control.setFocus()

	def reset(self):

		"""See base_console."""

		self.kernel.shell.reset()
		self.kernel.shell.push(self.default_globals())
		self.clear()
		super(ipython_console, self).reset()

	def show_prompt(self):

		"""See base_console."""

		self.control._show_interpreter_prompt()

	def get_workspace_globals(self):

		"""See base_console."""

		return self.kernel.shell.user_global_ns.copy()

	def set_workspace_globals(self, _globals={}):

		"""See base_console."""

		self.kernel.shell.push(_globals)

	def validTheme(self, cs):

		"""
		returns:
			desc:	True if the colorscheme is valid, False otherwise.
			type:	bool
		"""

		for key in [
			u'Background',
			u'Default',
			u'Prompt in',
			u'Prompt out',
			u'Comment',
			u'Keyword',
			u'Identifier',
			u'Double-quoted string',
			u'Invalid',
			u'Number',
			u'Operator',
			]:
			if key not in cs:
				return False
		return True

	def setTheme(self):

		"""
		desc:
			Sets the theme, based on the QProgEdit settings.
		"""

		from QProgEdit import QColorScheme
		if not hasattr(QColorScheme, cfg.qProgEditColorScheme):
			debug.msg(u'Failed to set debug-output colorscheme')
			return u''
		cs = getattr(QColorScheme, cfg.qProgEditColorScheme)
		if not self.validTheme(cs):
			debug.msg(u'Invalid debug-output colorscheme')
			return u''
		self.control._highlighter.set_style(pygments_style_factory(cs))
		qss = u'''QPlainTextEdit, QTextEdit {
				background-color: %(Background)s;
				color: %(Default)s;
			}
			.in-prompt { color: %(Prompt in)s; }
			.in-prompt-number { font-weight: bold; }
			.out-prompt { color: %(Prompt out)s; }
			.out-prompt-number { font-weight: bold; }
			''' % cs
		self.control.style_sheet = qss
		self.control._control.setFont(QtGui.QFont(cfg.qProgEditFontFamily,
			cfg.qProgEditFontSize))

	def setup(self, main_window):

		"""See base_subcomponent."""

		super(ipython_console, self).setup(main_window)
		self.kernel.shell.push(self.default_globals())

	def write(self, s):

		"""See base_console."""

		self.control._append_plain_text(str(s))

	def execute(self, s):

		"""See base_console."""

		self.main_window.ui.dock_stdout.setVisible(True)
		self.control.execute(s)

	def focusInEvent(self, e):

		self.control.setFocus()
		e.accept()
    def __init__(self, args):
        """Initializes application"""
        super(QSceneGraphEditor, self).__init__(args)

        self._mainWindow = QtGui.QMainWindow()
        self._editor = QSceneGraphEditorWindow()
        self._mainWindow.setCentralWidget(self._editor)
    
        exitAction = QtGui.QAction('&Exit', self._mainWindow)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self._mainWindow.close)

        newAction = QtGui.QAction('&New', self._mainWindow)
        newAction.setShortcut('Ctrl+N')
        newAction.setStatusTip('Creates a simple default scene')
        newAction.triggered.connect(self._editor.new)

        openAction = QtGui.QAction('&Open...', self._mainWindow)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Open scene graph from file')
        openAction.triggered.connect(self._editor.open)

        saveAction = QtGui.QAction('&Save', self._mainWindow)
        saveAction.setShortcut('Ctrl+S')
        saveAction.setStatusTip('Save scene graph')
        saveAction.triggered.connect(self._editor.save)

        saveAsAction = QtGui.QAction('&Save As...', self._mainWindow)
        saveAsAction.setStatusTip('Save scene graph to another file')
        saveAsAction.triggered.connect(self._editor.saveAs)

        insertObjectAction = QtGui.QAction('&Insert...', self._mainWindow)
        insertObjectAction.setShortcut('Ctrl+I')
        insertObjectAction.setStatusTip('Inserts new scene object before current one')
        insertObjectAction.triggered.connect(self._editor.inspectorWidget.insertObject)

        appendObjectAction = QtGui.QAction('&Append...', self._mainWindow)
        appendObjectAction.setShortcut('Ctrl+K')
        appendObjectAction.setStatusTip('Inserts new scene object after current one')
        appendObjectAction.triggered.connect(self._editor.inspectorWidget.appendObject)

        deleteObjectAction = QtGui.QAction('&Delete', self._mainWindow)
        deleteObjectAction.setShortcut('DEL')
        deleteObjectAction.setStatusTip('Deletes currently selected scene object')
        deleteObjectAction.triggered.connect(self._editor.inspectorWidget.deleteObject)

        refreshObjectAction = QtGui.QAction('&Refresh', self._mainWindow)
        refreshObjectAction.setShortcut('F5')
        refreshObjectAction.setStatusTip('Recreates tree view from root node')
        refreshObjectAction.triggered.connect(self._editor.refresh)

        viewAllAction = QtGui.QAction('View &All', self._mainWindow)
        viewAllAction.setShortcut('Ctrl+A')
        viewAllAction.setStatusTip('Resets camera in scene so all object are visible')
        viewAllAction.triggered.connect(self._editor.previewWidget.sceneManager.view_all)

        viewManipAction = QtGui.QAction('Camera &Manipulation', self._mainWindow)
        viewManipAction.setShortcut('Ctrl+M')
        viewManipAction.setStatusTip('Enables manipulation of camera in the scene')
        viewManipAction.setCheckable(True)
        viewManipAction.setChecked(True)
        viewManipAction.connect(QtCore.SIGNAL("triggered(bool)"), self._editor.previewWidget.sceneManager.interaction)
        self._editor.previewWidget.sceneManager.interaction(True)

        #self._mainWindow.statusBar()

        menubar = self._mainWindow.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(newAction)
        fileMenu.addAction(openAction)
        fileMenu.addAction(saveAction)
        fileMenu.addAction(saveAsAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)
    
        objectsMenu = menubar.addMenu('&Scene Object')
        objectsMenu.addAction(insertObjectAction)
        objectsMenu.addAction(appendObjectAction)
        objectsMenu.addAction(deleteObjectAction)
        objectsMenu.addSeparator()
        objectsMenu.addAction(refreshObjectAction)
    
        viewMenu = menubar.addMenu('&View')
        viewMenu.addAction(viewAllAction)
        viewMenu.addAction(viewManipAction)

        if "--ipython" in self.arguments():
            # start with IPython console at bottom of application
            from IPython.qt.console.rich_ipython_widget import RichIPythonWidget
            from IPython.qt.inprocess import QtInProcessKernelManager
            from IPython.lib import guisupport
            import inventor
            
            # Create an in-process kernel
            kernel_manager = QtInProcessKernelManager()
            kernel_manager.start_kernel()
            kernel = kernel_manager.kernel
            kernel.gui = 'qt4'
            kernel.shell.push({'iv': inventor, 'root': self._editor._root, 'view': self._editor.previewWidget.sceneManager })

            kernel_client = kernel_manager.client()
            kernel_client.start_channels()

            def stop():
                kernel_client.stop_channels()
                kernel_manager.shutdown_kernel()
                self.exit()

            control = RichIPythonWidget()
            control.kernel_manager = kernel_manager
            control.kernel_client = kernel_client
            control.exit_requested.connect(stop)
            control.font = QtGui.QFont(control.font.family(), 10);

            self.addVerticalWidget(control)

        # load default scene or from file if argument is given
        file = "#Inventor V2.1 ascii\n\nSeparator { " \
               "DirectionalLight {} OrthographicCamera { position 0 0 5 height 5 }" \
               "TrackballManip {} Material { diffuseColor 1 0 0 }" \
               "Cone {} }"
        if (len(self.arguments()) > 1) and ("." in self.arguments()[-1]):
            extension = self.arguments()[-1].split('.')[-1].lower()
            if extension in [ 'iv', 'vrml', '3ds', 'stl' ]:
                file = self.arguments()[-1];

        self._editor.load(file)
Exemple #50
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_()
Exemple #51
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()