def in_process_console(console_class=RichIPythonWidget, **kwargs): """Create a console widget, connected to an in-process Kernel This only works on IPython v 0.13 and above Parameters ---------- console_class : The class of the console widget to create kwargs : Extra variables to put into the namespace """ km = QtInProcessKernelManager() km.start_kernel() kernel = km.kernel kernel.gui = 'qt4' client = km.client() client.start_channels() control = console_class() control.kernel_manager = km control.kernel_client = client control.shell = kernel.shell control.shell.user_ns.update(**kwargs) return control
def __init__(self, client): QtWidgets.QWidget.__init__(self) self.client = client self.devices = {} # build layout layout = QtWidgets.QVBoxLayout(self) # tab widget for each connected device self.device_tabs = QtWidgets.QTabWidget() self.device_tabs.currentChanged.connect(self.onCurrentDeviceChanged) layout.addWidget(self.device_tabs) # ipython console for scripting kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel_client = kernel_manager.client() kernel_client.start_channels() self._console = RichIPythonWidget(font_size=9) self._console.kernel_manager = kernel_manager self._console.kernel_client = kernel_client layout.addWidget(self._console) # set device added and remove callbacks and connect client.deviceAdded.connect(self.addDevice) client.deviceRemoved.connect(self.removeDevice) client.connect() # push client and device map to console namespace dct = {"client": client, "devices": self.devices, "console": self._console} kernel_manager.kernel.shell.push(dct) self.resize(800, 500) self.setWindowTitle("Fpga Test Application")
def in_process_console(console_class=RichIPythonWidget, **kwargs): """Create a console widget, connected to an in-process Kernel This only works on IPython v 0.13 and above Parameters ---------- console_class : The class of the console widget to create kwargs : Extra variables to put into the namespace """ km = QtInProcessKernelManager() km.start_kernel() kernel = km.kernel kernel.gui = 'qt4' client = km.client() client.start_channels() control = console_class() control.kernel_manager = km control.kernel_client = client control.shell = kernel.shell control.shell.user_ns.update(**kwargs) return control
def createConsole(parent): """ disclaimer: this code is not mine. I copied it to get an embedded console It will be modified at some point to attempt interactability source: https://stackoverflow.com/a/26676570 :param parent: :return: """ kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() kernel_client.namespace = parent def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() layout = QVBoxLayout(parent) widget = RichJupyterWidget(parent=parent) layout.addWidget(widget, Qt.AlignRight) widget.kernel_manager = kernel_manager widget.kernel_client = kernel_client widget.exit_requested.connect(stop) ipython_widget = widget ipython_widget.show() kernel.shell.push({'widget': widget, 'kernel': kernel, 'parent': parent}) return {'widget': widget, 'kernel': kernel}
class JupyterWidget(RichJupyterWidget): def __init__(self): super(RichJupyterWidget, self).__init__() self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() guisupport.get_app_qt4().exit() self.exit_requested.connect(stop) def executeCmd(self, cmd): self.kernel.shell.ex(cmd) def evaluateCmd(self, cmd): self.kernel.shell.ev(cmd) def pushVar(self, **kwarg): self.kernel.shell.push(kwarg) def executeFile(self, file): """Execute a Python file in the interactive namespace.""" self.shell.safe_execfile(file, self.shell.user_global_ns) def runCell(self, *args, **kwargs): """Execute a cell.""" self.shell.run_cell(*args, **kwargs)
class LpyShellWidget(RichJupyterWidget): #, GraphicalStreamRedirection): def __init__(self, parent=None): """ :param parent: specifies the parent widget. If no parent widget has been specified, it is possible to exit the interpreter by Ctrl-D. """ if sys.executable.endswith('pythonw.exe'): lpylog = open(tempfile.gettempdir() + '/lpylog.txt', 'w') sys.stdout = lpylog sys.stderr = lpylog RichJupyterWidget.__init__(self, parent) self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel(show_banner=False) self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt' self.shell = self.kernel.shell self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.kernel.locals = self.kernel.shell.user_ns
def show(): """ An example of embedding a RichJupyterWidget with an in-process kernel. We recommend using a kernel in a separate process as the normal option - see embed_qtconsole.py for more information. In-process kernels are not well supported. To run this example: python3 inprocess_qtconsole.py """ #global ipython_widget # Prevent from being garbage collected # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel(show_banner=True) # kernel = kernel_manager.kernel # kernel.gui = 'qt5' kernel_client = kernel_manager.client() kernel_client.start_channels() ipython_widget = RichJupyterWidget() ipython_widget.kernel_manager = kernel_manager ipython_widget.kernel_client = kernel_client return ipython_widget
def __init__(self, *args, **kwargs): """ A constructor matching that of RichJupyterWidget :param args: Positional arguments passed directly to RichJupyterWidget :param kwargs: Keyword arguments. The following keywords are understood by this widget: - startup_code: A code snippet to run on startup. the rest are passed to RichJupyterWidget """ startup_code = kwargs.pop("startup_code", "") super(InProcessJupyterConsole, self).__init__(*args, **kwargs) # create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt' # use a separate thread for execution shell = kernel.shell shell.run_code = async_wrapper(shell.run_code, shell) # attach channels, start kernel and run any startup code kernel_client = kernel_manager.client() kernel_client.start_channels() if startup_code: shell.ex(startup_code) self.kernel_manager = kernel_manager self.kernel_client = kernel_client # Override python input to raise a QInputDialog. kernel.raw_input = QAppThreadCall(input_qinputdialog)
def __init__(self, session, tool_name): ToolInstance.__init__(self, session, tool_name) # 'display_name' defaults to class name with spaces inserted # between lower-then-upper-case characters (therefore "Tool UI" # in this case), so only override if different name desired self.display_name = "ChimeraX Python Shell" from chimerax.ui import MainToolWindow self.tool_window = MainToolWindow(self) parent = self.tool_window.ui_area # UI content code from ipykernel.ipkernel import IPythonKernel save_ns = IPythonKernel.user_ns IPythonKernel.user_ns = {'session': session} from qtconsole.inprocess import QtInProcessKernelManager kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel_client = kernel_manager.client() kernel_client.start_channels() from qtconsole.rich_jupyter_widget import RichJupyterWidget self.shell = RichJupyterWidget(parent) def_banner = self.shell.banner self.shell.banner = "{}\nCurrent ChimeraX session available as 'session'.\n\n".format( def_banner) self.shell.kernel_manager = kernel_manager self.shell.kernel_client = kernel_client IPythonKernel.user_ns = save_ns from PyQt5.QtWidgets import QHBoxLayout layout = QHBoxLayout() layout.addWidget(self.shell) layout.setStretchFactor(self.shell, 1) parent.setLayout(layout) self.tool_window.manage(placement=None)
def main(): """Start kernel manager and client, create window, run app event loop, auto execute some code in user namespace. A minimalist example is shown in qt_ip_test.py. NOTE: Make sure that the Qt v2 API is being used by IPython by running `export QT_API=pyqt` at the command line before running neuropy, or by adding it to `.bashrc`""" app = guisupport.get_app_qt4() if INPROCESS: from qtconsole.inprocess import QtInProcessKernelManager km = QtInProcessKernelManager() else: from qtconsole.manager import QtKernelManager km = QtKernelManager() km.start_kernel() km.kernel.gui = 'qt4' kc = km.client() kc.start_channels() nw = NeuropyWindow() ipw = nw.ipw config_ipw(ipw) ipw.kernel_manager = km ipw.kernel_client = kc ipw.exit_requested.connect(nw.stop) nw.show() # execute some code through the frontend (once the event loop is running). # The output appears in the IPythonWidget (ipw). do_later(ipw.execute, 'run -i %s' % 'startup.py', hidden=True) do_later(ipw.execute, 'run -i %s' % 'globals.py', hidden=True) #guisupport.start_event_loop_qt4(app) # doesn't seem to work in IPy 5.3.0 app.exec_()
def start_kernel_manager(self, silo, ui): kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel(show_banner=False) kernel_manager.kernel.gui = 'qt' def EulerAngles(name, roll, pitch, yaw, *args, **kwargs): from signal_logger.rotation_signals import EulerAnglesZyxSignal return EulerAnglesZyxSignal.from_constant(name, silo.times, roll, pitch, yaw, *args, **kwargs) def clf(): import pylab pylab.clf() ui.tab.ui.canvas.canvas.draw() def plot(signal, *args, **kwargs): # TODO(scaron): currently plots to the right axis, give choice signal.plot(*args, **kwargs) ui.tab.ui.canvas.canvas.draw() kernel_manager.kernel.shell.push({ 'EulerAngles': EulerAngles, 'clf': clf, 'plot': plot, 'pi': numpy.pi, 'silo': silo, 'ui': ui, }) self.kernel_manager = kernel_manager
def main(): # Print the ID of the main process print_process_id() init_asyncio_patch() app = guisupport.get_app_qt4() # Create an in-process kernel # >>> print_process_id() # will print the same process ID as the main process kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel.shell.push({'foo': 43, 'print_process_id': print_process_id}) kernel_client = kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() app.exit() control = RichIPythonWidget() control.kernel_manager = kernel_manager control.kernel_client = kernel_client control.exit_requested.connect(stop) control.show() guisupport.start_event_loop_qt4(app)
def __init__(self, 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 = QtWidgets.QVBoxLayout(self) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.verticalLayout) self.verticalLayout.addWidget(self.control)
def put_ipy(parent): kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() kernel_client.namespace = parent def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() layout = QtWidgets.QVBoxLayout(parent) widget = RichJupyterWidget(parent=parent) layout.addWidget(widget) widget.kernel_manager = kernel_manager widget.kernel_client = kernel_client widget.exit_requested.connect(stop) ipython_widget = widget ipython_widget.show() kernel.shell.push({'widget': widget, 'kernel': kernel, 'parent': parent}) return {'widget': widget, 'kernel': kernel}
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 = QtWidgets.QVBoxLayout(self) self.verticalLayout.setContentsMargins(0,0,0,0) self.setLayout(self.verticalLayout) self.verticalLayout.addWidget(self.control)
def __init__(self, *args, **kwargs): """ Parameters ---------- help_explorer: psyplot_gui.help_explorer.HelpExplorer or None A widget that can be used to show the documentation of an object ``*args, **kwargs`` Any other keyword argument for the :class:`qtconsole.rich_jupyter_widget.RichJupyterWidget """ kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel(show_banner=False) kernel = kernel_manager.kernel kernel.gui = 'qt4' if not with_qt5 else 'qt' kernel_client = kernel_manager.client() kernel_client.start_channels() self.help_explorer = kwargs.pop('help_explorer', None) super(ConsoleWidget, self).__init__(*args, **kwargs) self.intro_msg = dedents(""" psyplot version: %s gui version: %s The console provides you the full access to the current project and plots. To make your life easier, the following modules have been imported - %s Furthermore, each time you change the selection or the content in the plot objects viewer, the `sp` (the selection) and `mp` (all arrays) variables in the console are adjusted. To disable this behaviour, set:: >>> import psyplot_gui >>> psyplot_gui.rcParams['console.auto_set_mp'] = False >>> psyplot_gui.rcParams['console.auto_set_sp'] = False To inspect and object in the console and display it's documentation in the help explorer, type 'Ctrl + I' or a '?' after the object""") % ( psyplot.__version__, psyplot_gui.__version__, '\n - '.join('%s as %s' % t for t in modules2import)) self.kernel_manager = kernel_manager self.kernel_client = kernel_client self.kernel_manager.kernel.shell.run_code( '\n'.join('import %s as %s' % t for t in modules2import)) self.exit_requested.connect(QtCore.QCoreApplication.instance().quit) # we overwrite the short cut here because the 'Ctrl+S' shortcut is # reserved for mainwindows save action self.export_action.setShortcut(QKeySequence( 'Ctrl+Alt+S', QKeySequence.NativeText)) psy.Project.oncpchange.connect(self.update_mp) psy.Project.oncpchange.connect(self.update_sp)
def main(): """Start kernel manager and client, create window, run app event loop""" app = guisupport.get_app_qt4() if INPROCESS: from qtconsole.inprocess import QtInProcessKernelManager km = QtInProcessKernelManager() else: from qtconsole.manager import QtKernelManager km = QtKernelManager() km.start_kernel() km.kernel.gui = 'qt4' kc = km.client() kc.start_channels() widget = RichJupyterWidget() widget.kernel_manager = km widget.kernel_client = kc if CLEANSHUTDOWN: # slow exit on CTRL+D def stop(): kc.stop_channels() km.shutdown_kernel() app.exit() widget.exit_requested.connect(stop) else: # fast exit on CTRL+D widget.exit_requested.connect(app.quit) widget.show() guisupport.start_event_loop_qt4(app)
def put_ipy(parent): kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() kernel_client.namespace = parent #kernel.execute_request("a=1",0, {'silent': False}) def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() layout = _gui.QVBoxLayout(parent) widget = RichIPythonWidget(parent=parent) layout.addWidget(widget) widget.kernel_manager = kernel_manager widget.kernel_client = kernel_client widget.exit_requested.connect(stop) ipython_widget = widget ipython_widget.show() kernel.shell.push({'widget':widget,'kernel':kernel, 'parent':parent}) return {'widget':widget,'kernel':kernel}
class JupyterWidget(QWidget): _defaultWidth = 900 _defaultHeight = 450 def __init__(self): super(JupyterWidget, self).__init__() self._kernel_manager = QtInProcessKernelManager() self._kernel_manager.start_kernel(show_banner=True) self._kernel_client = self._kernel_manager.client() self._kernel_client.start_channels() self._kernel = self._kernel_manager.kernel self._kernel.gui = 'qt4' self._console = RichJupyterWidget() self._console.kernel_manager = self._kernel_manager self._console.kernel_client = self._kernel_client self._layout = QHBoxLayout() self._layout.addWidget(self._console) self._layout.setContentsMargins(QMargins(0, 0, 0, 0)) self.setLayout(self._layout) self.resize(self._defaultWidth, self._defaultHeight) def push(self, name, value): self._kernel.shell.push({name: value})
class LpyShellWidget(RichJupyterWidget, GraphicalStreamRedirection): def __init__(self, parent=None): """ :param parent: specifies the parent widget. If no parent widget has been specified, it is possible to exit the interpreter by Ctrl-D. """ RichJupyterWidget.__init__(self, parent) self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel(show_banner=False) 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.kernel.locals = self.kernel.shell.user_ns # Multiple Stream Redirection GraphicalStreamRedirection.__init__(self, self.kernel.stdout, self.kernel.stderr)
def __init__(self, *args, **kw): super(MantidIPythonWidget, self).__init__(*args, **kw) # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' # Figure out the full path to the mantidplotrc.py file and then %run it mantidplotpath = path.split( path.dirname(__file__))[0] # It's the directory above this one # print '[....] mantid plot path: ', mantidplotpath mantidplotrc = path.join(mantidplotpath, 'mantidplotrc.py') shell = kernel.shell shell.run_line_magic('run', mantidplotrc) # print '[DB...BAUnderstand]: shell run: ', mantidplotrc # These 3 lines replace the run_code method of IPython's InteractiveShell class (of which the # shell variable is a derived instance) with our method defined above. The original method # is renamed so that we can call it from within the our_run_code method. f = shell.run_code shell.run_code = types.MethodType(our_run_code, shell) shell.ipython_run_code = f kernel_client = kernel_manager.client() kernel_client.start_channels() self.kernel_manager = kernel_manager self.kernel_client = kernel_client self._mainApplication = None return
def __init__(self, *args, **kw): super(MantidIPythonWidget, self).__init__(*args, **kw) # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' # Figure out the full path to the mantidplotrc.py file and then %run it from os import path mantidplotpath = path.split(path.dirname(__file__))[0] # It's the directory above this one mantidplotrc = path.join(mantidplotpath, 'mantidplotrc.py') shell = kernel.shell shell.run_line_magic('run',mantidplotrc) # These 3 lines replace the run_code method of IPython's InteractiveShell class (of which the # shell variable is a derived instance) with our method defined above. The original method # is renamed so that we can call it from within the our_run_code method. f = shell.run_code shell.run_code = types.MethodType(our_run_code, shell) shell.ipython_run_code = f kernel_client = kernel_manager.client() kernel_client.start_channels() self.kernel_manager = kernel_manager self.kernel_client = kernel_client
def main(): """Start kernel manager and client, create window, run app event loop, auto execute some code in user namespace. A minimalist example is shown in qt_ip_test.py. NOTE: Make sure that the Qt v2 API is being used by IPython by running `export QT_API=pyqt` at the command line before running neuropy, or by adding it to `.bashrc`""" app = guisupport.get_app_qt4() if INPROCESS: from qtconsole.inprocess import QtInProcessKernelManager km = QtInProcessKernelManager() else: from qtconsole.manager import QtKernelManager km = QtKernelManager() km.start_kernel() km.kernel.gui = 'qt4' kc = km.client() kc.start_channels() nw = NeuropyWindow() ipw = nw.ipw config_ipw(ipw) ipw.kernel_manager = km ipw.kernel_client = kc ipw.exit_requested.connect(nw.stop) nw.show() # execute some code through the frontend (once the event loop is running). # The output appears in the IPythonWidget (ipw). do_later(ipw.execute, 'run -i %s' % 'startup.py', hidden=True) do_later(ipw.execute, 'run -i %s' % 'globals.py', hidden=True) #guisupport.start_event_loop_qt4(app) # doesn't seem to work in IPy 5.3.0 app.exec_()
class ConsoleWidget_embed(RichJupyterWidget, ConsoleWidget): global fit def __init__(self, customBanner=None, *args, **kwargs): super(ConsoleWidget_embed, self).__init__(*args, **kwargs) if customBanner is not None: self.banner = customBanner #self.font_size = 4 self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel(show_banner=True) self.kernel_manager.kernel.gui = 'qt' self.kernel = self.kernel_manager.kernel self.kernel_client = self._kernel_manager.client() self.kernel_client.start_channels() def _abort_queues(kernel): pass self.kernel_manager.kernel._abort_queues = _abort_queues #self._execute("kernel = %s"%fit, False) def stop(): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() self.guisupport.get_app_qt().exit() self.exit_requested.connect(stop) def push_vars(self, variableDict): """ Given a dictionary containing name / value pairs, push those variables to the Jupyter console widget """ self.kernel_manager.kernel.shell.push(variableDict) def clear(self): """ Clears the terminal """ self._control.clear() # self.kernel_manager def print_text(self, text, before_prompt=True): """ Prints some plain text to the console """ self._append_plain_text(text, before_prompt=before_prompt) def execute_command(self, command): """ Execute a command in the frame of the console widget """ self._execute(command, False)
def start_in_process_kernel(): global kernel_manager, kernel_client kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel_client = kernel_manager.client() kernel_client.start_channels()
class JupyterWidget(RichJupyterWidget): def __init__(self): super().__init__() if 'asyncio' in sys.modules: self._init_asyncio_patch() self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() # Fix issue with Jupyter 5.0+, see https://github.com/ipython/ipykernel/pull/376 if hasattr(self.kernel_manager.kernel, '_abort_queue'): # noinspection PyProtectedMember self.kernel_manager.kernel._abort_queues = self.kernel_manager.kernel._abort_queue self.exit_requested.connect(self.stop) qApp.aboutToQuit.connect(self.stop) def _init_asyncio_patch(self): """set default asyncio policy to be compatible with tornado Tornado 6 (at least) is not compatible with the default asyncio implementation on Windows Pick the older SelectorEventLoopPolicy on Windows if the known-incompatible default policy is in use. do this as early as possible to make it a low priority and overrideable ref: https://github.com/tornadoweb/tornado/issues/2608 FIXME: if/when tornado supports the defaults in asyncio, remove and bump tornado requirement for py38 """ if sys.platform.startswith("win") and sys.version_info >= ( 3, 8) and tornado.version_info < (6, 1): import asyncio try: from asyncio import ( WindowsProactorEventLoopPolicy, WindowsSelectorEventLoopPolicy, ) except ImportError: pass # not affected else: if type(asyncio.get_event_loop_policy() ) is WindowsProactorEventLoopPolicy: # WindowsProactorEventLoopPolicy is not compatible with tornado 6 # fallback to the pre-3.8 default of Selector asyncio.set_event_loop_policy( WindowsSelectorEventLoopPolicy()) def stop(self): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() def push(self, **kwargs): self.kernel_manager.kernel.shell.push(kwargs)
def start_in_process_kernel(): global kernel_manager, kernel_client kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel_client = kernel_manager.client() kernel_client.start_channels()
class IPythonPlugin(GUIPlugin): name = 'IPython' def __init__(self): # # Enforce global style within the console # with open('xicam/gui/style.stylesheet', 'r') as f: # style = f.read() # style = (qdarkstyle.load_stylesheet() + style) # Setup the kernel self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() kernel = self.kernel_manager.kernel kernel.gui = 'qt' # Push Xi-cam variables into the kernel kernel.shell.push({ plugin.name: plugin for plugin in pluginmanager.get_plugins_of_type("GUIPlugin") + pluginmanager.get_plugins_of_type("EZPlugin") }) # Observe plugin changes pluginmanager.attach(self.pluginsChanged) # Continue kernel setuppluginmanager.getPluginsOfCategory("GUIPlugin") self.kernel_client = self.kernel_manager.client() threads.invoke_in_main_thread(self.kernel_client.start_channels) # Setup console widget def stop(): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() control = RichJupyterWidget() control.kernel_manager = self.kernel_manager threads.invoke_in_main_thread(setattr, control, "kernel_client", self.kernel_client) control.exit_requested.connect(stop) # control.style_sheet = style control.syntax_style = u'monokai' control.set_default_style(colors='Linux') # Setup layout self.stages = {'Terminal': GUILayout(control)} # Save for later self.kernel = kernel super(IPythonPlugin, self).__init__() def pluginsChanged(self): self.kernel.shell.push({ plugin.name: plugin for plugin in pluginmanager.get_plugins_of_type("GUIPlugin") + pluginmanager.get_plugins_of_type("EZPlugin") })
class EmbedIPython(RichIPythonWidget): def __init__(self, **kwarg): super(RichIPythonWidget, self).__init__() self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push(kwarg) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels()
class EmbedIPython(RichIPythonWidget): def __init__(self, **kwarg): super(RichIPythonWidget, self).__init__() self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push(kwarg) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels()
def init_jupyter_kernel(cls, widget): """Start a kernel, connect to it, and create a RichJupyterWidget to use it """ kernel_manager = QtInProcessKernelManager(kernel_name="python3") kernel_manager.start_kernel() kernel_client = kernel_manager.client() kernel_client.start_channels() widget.kernel_manager = kernel_manager widget.kernel_client = kernel_client
class EmbedIPython(RichJupyterWidget): """ Some voodoo to get an ipython console in a Qt application. """ def __init__(self, **kwarg): super(RichJupyterWidget, self).__init__() self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push(kwarg) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels()
class Ipython(object): def __init__(self, scripts_path=''): self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel sys.stdout = self.kernel.stdout sys.stderr = self.kernel.stderr self.scripts_path = scripts_path self.kernel.gui = 'qt4' self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.control = RichJupyterWidget() self.control.kernel_manager = self.kernel_manager self.control.kernel_client = self.kernel_client self.control.exit_requested.connect(self.stop) self.control.setWindowTitle("IPython shell") self.execute('import numpy as np') self.execute('from matplotlib import pyplot as plt') self.execute('%matplotlib') self.execute('') def __del__(self): self.stop() self.close() def show(self): self.control.show() self.control.setWindowState(self.control.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) self.control.activateWindow() def stop(self): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() def close(self): self.control.close() def push(self, vardic): self.kernel.shell.push(vardic) def execute(self, cmd): self.control.execute(cmd) def run_script(self, scriptname): scriptpath = os.path.join(self.scripts_path, scriptname) return self.control.execute('run -i %s' % scriptpath)
class EmbedIPython(RichIPythonWidget): def __init__(self, parent=None): super(RichIPythonWidget, self).__init__(parent) self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' # self.kernel.shell.push(kwarg) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.kernel.shell.run_cell('%pylab qt')
class IPythonView(RichJupyterWidget): """A view with an IPython console living in the same Python process as the GUI.""" def __init__(self, *args, **kwargs): super(IPythonView, self).__init__(*args, **kwargs) def start_kernel(self): """Start the IPython kernel.""" logger.debug("Starting the kernel.") self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel(show_banner=False) self.kernel_manager.kernel.gui = 'qt' self.kernel = self.kernel_manager.kernel self.shell = self.kernel.shell self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.set_default_style('linux') self.exit_requested.connect(self.stop) def inject(self, **kwargs): """Inject variables into the IPython namespace.""" logger.debug("Injecting variables into the kernel: %s.", ', '.join(kwargs.keys())) self.kernel.shell.push(kwargs) def attach(self, gui, **kwargs): """Add the view to the GUI, start the kernel, and inject the specified variables.""" gui.add_view(self) self.start_kernel() self.inject(gui=gui, **kwargs) try: import numpy self.inject(np=numpy) except ImportError: # pragma: no cover pass try: import matplotlib.pyplot as plt self.inject(plt=plt) except ImportError: # pragma: no cover pass @connect def on_close_view(sender, view): if view == self: self.stop() def stop(self): """Stop the kernel.""" logger.debug("Stopping the kernel.") self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel()
class IPythonConsole: def __init__(self, layout, sim, gui): # 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.write("Welcome to AO Sim!") config = sim.config #Pass some useful objects to the user usefulObjects = { "sim": sim, "gui": gui, "config": config, "simConfig": sim.config.sim, "telConfig": sim.config.tel, "atmosConfig": sim.config.atmos } for i in range(sim.config.sim.nGS): usefulObjects["wfs{}Config".format(i)] = sim.config.wfss[i] for i in range(sim.config.sim.nDM): usefulObjects["dm{}Config".format(i)] = sim.config.dms[i] for i in range(sim.config.sim.nSci): usefulObjects["sci{}Config".format(i)] = sim.config.scis[i] self.kernel.shell.push(usefulObjects) #kernel.shell.push({'foo': 43, 'print_process_id': print_process_id}) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() control = RichIPythonWidget() control.kernel_manager = self.kernel_manager control.kernel_client = self.kernel_client control.exit_requested.connect(self.stop) layout.addWidget(control) self.kernel.shell.ex("") #control.show() #self.kernel.show def stop(self): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() def write(self, message): self.kernel.shell.write(message) self.kernel.shell.ex("")
class ConsoleWidget(RichJupyterWidget): """ Convenience class for a live IPython console widget. We can replace the standard banner using the customBanner argument """ def __init__(self, customBanner=None, *args, **kwargs): RichJupyterWidget.__init__(self, *args, **kwargs) if customBanner is not None: self.banner = customBanner self.font_size = 6 self.gui_completion = 'droplist' self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel(show_banner=False) self.kernel_manager.kernel.gui = 'qt' self.kernel_client = kernel_client = self._kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() # guisupport.get_app_qt().exit() self.exit_requested.connect(stop) def push_vars(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 clear(self): """ Clears the terminal """ self._control.clear() # self.kernel_manager def print_text(self, text): """ Prints some plain text to the console """ self._append_plain_text(text) def execute_command(self, command): """ Execute a command in the frame of the console widget """ self._execute(command, False)
class IPythonConsole: def __init__(self, layout, sim, gui): # 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.write("Welcome to AO Sim!") config = sim.config #Pass some useful objects to the user usefulObjects = { "sim" : sim, "gui" : gui, "config" : config, "simConfig" : sim.config.sim, "telConfig" : sim.config.tel, "atmosConfig" : sim.config.atmos} for i in range(sim.config.sim.nGS): usefulObjects["wfs{}Config".format(i)] = sim.config.wfss[i] for i in range(sim.config.sim.nDM): usefulObjects["dm{}Config".format(i)] = sim.config.dms[i] for i in range(sim.config.sim.nSci): usefulObjects["sci{}Config".format(i)] = sim.config.scis[i] self.kernel.shell.push(usefulObjects) #kernel.shell.push({'foo': 43, 'print_process_id': print_process_id}) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() control = RichIPythonWidget() control.kernel_manager = self.kernel_manager control.kernel_client = self.kernel_client control.exit_requested.connect(self.stop) layout.addWidget(control) self.kernel.shell.ex("") #control.show() #self.kernel.show def stop(self): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() def write(self,message): self.kernel.shell.write(message) self.kernel.shell.ex("")
def __init__(self, interpreter=None, message="", log='', parent=None): """ :param interpreter : InteractiveInterpreter in which the code will be executed :param message: welcome message string :param parent: specifies the parent widget. If no parent widget has been specified, it is possible to exit the interpreter by Ctrl-D. """ RichJupyterWidget.__init__(self, parent) if interpreter is None: from openalea.core.service.ipython import interpreter interpreter = interpreter() # Set interpreter self.interpreter = interpreter # Set kernel manager km = QtInProcessKernelManager() km.start_kernel(show_banner=False) self.kernel_manager = km #km.kernel = self.interpreter #km.kernel.gui = 'qt4' self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt' #self.interpreter = self.kernel self.shell = self.kernel.shell self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.kernel.locals = self.kernel.shell.user_ns # For Debug Only # self.interpreter.locals['shell'] = self # Compatibility with visualea self.runsource = self.interpreter.run_cell self.runcode = self.interpreter.runcode self.loadcode = self.interpreter.loadcode # Write welcome message self.interpreter.widget = self #self.write(message) # Multiple Stream Redirection GraphicalStreamRedirection.__init__(self, self.kernel.stdout, self.kernel.stderr)
def __init__(self): RichJupyterWidget.__init__(self) # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel(show_banner=False) kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() self.kernel_manager = kernel_manager self.kernel_client = kernel_client
class IPythonConsole: def __init__(self, layout, sim, gui): # Create an in-process kernel self.kernel_manager = QtInProcessKernelManager() # self.kernel_manager = QtKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel # self.kernel.shell.write("Welcome to AO Sim!\n") config = sim.config #Pass some useful objects to the user usefulObjects = { "sim": sim, "gui": gui, "config": config, "simConfig": sim.config.sim, "telConfig": sim.config.tel, "atmosConfig": sim.config.atmos, "np": numpy, "plt": pyplot } for i in range(sim.config.sim.nGS): usefulObjects["wfs{}Config".format(i)] = sim.config.wfss[i] for i in range(sim.config.sim.nDM): usefulObjects["dm{}Config".format(i)] = sim.config.dms[i] for i in range(sim.config.sim.nSci): usefulObjects["sci{}Config".format(i)] = sim.config.scis[i] self.kernel.shell.push(usefulObjects) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() control = RichIPythonWidget() control.kernel_manager = self.kernel_manager control.kernel_client = self.kernel_client control.exit_requested.connect(self.stop) layout.addWidget(control) # self.kernel.shell.ex("") def stop(self): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() def write(self, message): pass
class IPythonConsole: def __init__(self, layout, sim, gui): # Create an in-process kernel self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.shell.write("Welcome to AO Sim!\n") config = sim.config #Pass some useful objects to the user usefulObjects = { "sim" : sim, "gui" : gui, "config" : config, "simConfig" : sim.config.sim, "telConfig" : sim.config.tel, "atmosConfig" : sim.config.atmos, "np" : numpy, "plt" : pyplot} for i in range(sim.config.sim.nGS): usefulObjects["wfs{}Config".format(i)] = sim.config.wfss[i] for i in range(sim.config.sim.nDM): usefulObjects["dm{}Config".format(i)] = sim.config.dms[i] for i in range(sim.config.sim.nSci): usefulObjects["sci{}Config".format(i)] = sim.config.scis[i] self.kernel.shell.push(usefulObjects) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() control = RichIPythonWidget() control.kernel_manager = self.kernel_manager control.kernel_client = self.kernel_client control.exit_requested.connect(self.stop) layout.addWidget(control) self.kernel.shell.ex("") def stop(self): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() def write(self,message): self.kernel.shell.write(message) self.kernel.shell.ex("")
def __init__(self, *args, **kwargs): """ A constructor matching that of RichJupyterWidget :param args: Positional arguments passed directly to RichJupyterWidget :param kwargs: Keyword arguments. The following keywords are understood by this widget: - banner: Replace the default banner with this text - startup_code: A code snippet to run on startup. It is also added to the banner to inform the user. the rest are passed to RichJupyterWidget """ banner = kwargs.pop("banner", "") startup_code = kwargs.pop("startup_code", "") super(InProcessJupyterConsole, self).__init__(*args, **kwargs) # adjust startup banner accordingly # newer ipython has banner1 & banner2 and not just banner two_ptr_banner = hasattr(self, 'banner1') if not banner: banner = self.banner1 if two_ptr_banner else self.banner if startup_code: banner += "\n" + \ "The following code has been executed at startup:\n\n" + \ startup_code if two_ptr_banner: self.banner1 = banner self.banner2 = '' else: self.banner = banner # create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt' # use a separate thread for execution shell = kernel.shell shell.run_code = async_wrapper(shell.run_code, shell) # attach channels, start kenel and run any startup code kernel_client = kernel_manager.client() kernel_client.start_channels() if startup_code: shell.ex(startup_code) self.kernel_manager = kernel_manager self.kernel_client = kernel_client
def _setup_kernel(self): """ Setup the kernel for the widget. """ kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel(show_banner=False) kernel = kernel_manager.kernel kernel.gui = 'qt' kernel_client = kernel_manager.client() kernel_client.start_channels() ipy_widget = self.ipy_widget ipy_widget.kernel_manager = kernel_manager ipy_widget.kernel_client = kernel_client
def show(): global ipython_widget # Prevent from being garbage collected # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel(show_banner=False) kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() ipython_widget = RichJupyterWidget() ipython_widget.kernel_manager = kernel_manager ipython_widget.kernel_client = kernel_client ipython_widget.show()
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 = RichJupyterWidget() control.kernel_manager = kernel_manager control.kernel_client = kernel_client return control
def __init__(self, *args, **kw): super(IPythonWidget, self).__init__(*args, **kw) # Create an in-process kernel kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt' kernel_client = kernel_manager.client() kernel_client.start_channels() self.kernel_manager = kernel_manager self.kernel_client = kernel_client if not in_mantidplot(): self.execute('from mslice.util.mantid.mantid_algorithms import *', hidden=True) self.execute('from mslice.cli import *', hidden=True) else: self.execute('import mslice.cli as mc')
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)
class EmbedIPython(RichIPythonWidget): """ Based on: http://stackoverflow.com/questions/11513132/embedding-ipython-qt-console-in-a-pyqt-application """ def __init__(self, **kwarg): super(RichIPythonWidget, self).__init__() self.app = app = guisupport.get_app_qt4() self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel.gui = 'qt4' self.kernel.shell.push(kwarg) self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() def get_kernel_shell(self): return self.kernel_manager.kernel.shell def get_kernel_shell_user(self): return self.kernel_manager.kernel.shell.user_ns
def __init__(self, *args, **kwargs): super(ConsoleWidget, self).__init__(*args, **kwargs) # Create an in-process kernel app = guisupport.get_app_qt4() kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() # Set the kernel data self.kernel = kernel_manager.kernel self.kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() app.exit() self.kernel_manager = kernel_manager self.kernel_client = kernel_client self.exit_requested.connect(stop)
def embed_ipy(parent, passthrough=None): """ Embed an ipython kernel into the parent widget using a RichJupyterWidget :param parent: Qt Widget to receive the RichJupyterWidget :param passthrough: dict containing variables to pass into scope of the IPython Kernel Use this with caution; strange things can happen if you pass GUI elements to the IPython scope and then call any of their show() or draw() methods. :return: dict with reference to jupyter widget and ipython kernel """ kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() kernel = kernel_manager.kernel kernel.gui = 'qt4' kernel_client = kernel_manager.client() kernel_client.start_channels() kernel_client.namespace = parent def stop(): kernel_client.stop_channels() kernel_manager.shutdown_kernel() layout = QtGui.QVBoxLayout(parent) widget = RichJupyterWidget(parent=parent) layout.addWidget(widget) widget.kernel_manager = kernel_manager widget.kernel_client = kernel_client widget.exit_requested.connect(stop) ipython_widget = widget ipython_widget.show() kernel.shell.push({'widget': widget, 'kernel': kernel, 'parent': parent}) # pass variables from main GUI environment into IPython Kernel namespace if passthrough is not None: kernel.shell.push(passthrough) # variables stored in this dict are now accessible in the IPython shell return {'widget': widget, 'kernel': kernel}
class QtipWindow(QtGui.QMainWindow): """Main Qtip window class""" def __init__(self, parent=None, engine='pint', \ parfile=None, timfile=None, **kwargs): """ Initialize the main window :param parent: The parent window that embeds the Qtip window :param engine: The preferred timing package to use ('pint'/'libstempo') ['pint'] :param parfile: Par-file top open on startup :param timfile: Tim-file top open on startup """ super(QtipWindow, self).__init__(parent) self.setWindowTitle('Jupyter interface for pulsar timing') # Initialise basic gui elements self.initUI() # Start the embedded Jupyter kernel self.createJupyterKernel() # Create the display widgets self.createPlkWidget() self.createJupyterWidget() self.createOpenSomethingWidget() # Position the widgets self.initQtipLayout() # Initialize the main widget (the plk emulator) self.setQtipLayout(whichWidget='plk', showJupyter=False, firsttime=True) # The preferred engine to use (PINT) self.pref_engine = engine # We are still in MAJOR testing mode, so open a test-pulsar right away # if no par/tim file is given if parfile is None or timfile is None: testpulsar = True else: testpulsar = False # Open plk as the main widget self.requestOpenPlk(testpulsar=testpulsar, parfilename=parfile, \ timfilename=timfile, engine=self.pref_engine) self.show() def __del__(self): pass def onAbout(self): """Show an about box""" msg = constants.QtipBanner QtGui.QMessageBox.about(self, "About Qtip", 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 # Menu item: open par/tim files self.openParTimAction = QtGui.QAction('&Open par/tim', self) self.openParTimAction.setShortcut('Ctrl+O') self.openParTimAction.setStatusTip('Open par/tim') self.openParTimAction.triggered.connect(self.openParTim) # Menu item: exit Qtip 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) # Previously, it was possible to switch out the 'plk' widget for another # main widget (the binary pulsar one). That one has been stripped out # now, so for now it makes no sense to 'toggle' on or off the plk # widget. However, the option is still there for now... self.togglePlkAction = QtGui.QAction('&Plk', self) self.togglePlkAction.setShortcut('Ctrl+P') self.togglePlkAction.setStatusTip('Toggle plk widget') self.togglePlkAction.triggered.connect(self.togglePlk) # Menu item: toggle the Jupyter window self.toggleJupyterAction = QtGui.QAction('&Jupyter', self) self.toggleJupyterAction.setShortcut('Ctrl+J') self.toggleJupyterAction.setStatusTip('Toggle Jupyter') self.toggleJupyterAction.triggered.connect(self.toggleJupyter) # Menu item: about Qtip self.aboutAction = QtGui.QAction('&About', self) self.aboutAction.setShortcut('Ctrl+A') self.aboutAction.setStatusTip('About Qtip') self.aboutAction.triggered.connect(self.onAbout) # The status bar self.theStatusBar = QtGui.QStatusBar() #self.statusBar() self.setStatusBar(self.theStatusBar) # A label that shows what engine is being used (hardcoded: PINT) self.engine_label = QtGui.QLabel("PINT") 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 bar, and link the action items 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.togglePlkAction) self.viewMenu.addAction(self.toggleJupyterAction) self.helpMenu = self.menubar.addMenu('&Help') self.helpMenu.addAction(self.aboutAction) # What is the status quo of the user interface? self.showJupyter = False self.whichWidget = 'None' self.prevShowJupyter = None self.prevWhichWidget = 'None' def createJupyterKernel(self): """Create and start the embedded Jupyter Kernel""" # Create an in-process kernel self.kernelManager = QtInProcessKernelManager() self.kernelManager.start_kernel() self.kernel = self.kernelManager.kernel # Launch the kernel self.kernelClient = self.kernelManager.client() self.kernelClient.start_channels() # Allow inline matplotlib figures self.kernel.shell.enable_matplotlib(gui='inline') # Load the necessary packages in the embedded kernel # TODO: show this line in a cell of it's own 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 createJupyterWidget(self): """Create the Jupyter widget""" self.consoleWidget = RichJupyterWidget() #self.consoleWidget.setMinimumSize(600, 550) # Show the banner self.consoleWidget.banner = constants.QtipBanner self.consoleWidget.kernel_manager = self.kernelManager # Couple the client self.consoleWidget.kernel_client = self.kernelClient self.consoleWidget.exit_requested.connect(self.toggleJupyter) self.consoleWidget.set_default_style(colors='linux') self.consoleWidget.hide() # Register a call-back function for the Jupyter shell. This one is # executed insite the child-kernel. #self.kernel.shell.register_post_execute(self.postExecute) # # In Jupyter >= 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: This widget should become the first main widget to see? At the moment, we're avoiding it for the sake of testing purposes """ 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 toggleJupyter(self): """Toggle the Jupyter widget on or off""" self.setQtipLayout(showJupyter = not self.showJupyter) def togglePlk(self): """Toggle the plk widget on or off""" self.setQtipLayout(whichWidget='plk') def initQtipLayout(self): """Initialise the Qtip layout""" # If other 'main' widgets exist, they can be added here self.hbox.addWidget(self.openSomethingWidget) self.hbox.addWidget(self.plkWidget) 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 # No, hiding seems to work better """ 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.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() # Other widgets can be added here if self.showJupyter: self.consoleWidget.show() else: pass # Request focus back to the main widget if self.whichWidget.lower() == 'plk' and not self.showJupyter: self.plkWidget.setFocusToCanvas() # Do it for other main widgets, if they exist #elif self.whichWidget.lower() == 'binary' and not self.showJupyter: # self.binaryWidget.setFocusToCanvas() # Do we immediately get focus to the Jupyter console? #elif self.showJupyter: # self.consoleWidget.setFocus() def setQtipLayout(self, whichWidget=None, showJupyter=None, firsttime=False): """Given the current main widget, hide all the other widgets :param whichWidget: Which main widget we are showing right now :param showJupyter: Whether to show the Jupyter console :param firsttime: Whether or not this is the first time setting the layout. If so, resize to proper dimensions. TODO: How to do this more elegantly? """ if not whichWidget is None: self.whichWidget = whichWidget if not showJupyter is None: self.showJupyter = showJupyter # After hiding the widgets, wait 0 milliseonds before showing them again # (what a dirty hack, ugh!) self.hideAllWidgets() QtCore.QTimer.singleShot(0, self.showVisibleWidgets) self.prevWhichWidget = self.whichWidget if self.showJupyter != self.prevShowJupyter: # Jupyter has been toggled self.prevShowJupyter = self.showJupyter if self.showJupyter: self.resize(1350, 550) self.mainFrame.resize(1350, 550) else: self.resize(650, 550) self.mainFrame.resize(650, 550) # TODO: How to do this more elegantly? if firsttime: # Set position slightly more to the left of the screen, so we can # still open Jupyter self.move(50, 100) self.mainFrame.setLayout(self.hbox) self.mainFrame.show() def requestOpenPlk(self, parfilename=None, timfilename=None, \ testpulsar=False, engine='pint'): """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', showJupyter=self.showJupyter) 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.openPlkPulsar(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): """Open a par-file and a tim-file""" # Ask the user for a par and tim file, and open these with libstempo/pint parfilename = QtGui.QFileDialog.getOpenFileName(self, 'Open par-file', '~/') timfilename = QtGui.QFileDialog.getOpenFileName(self, 'Open tim-file', '~/') # Load the pulsar self.openPlkPulsar(parfilename, timfilename, engine=self.pref_engine) def openPlkPulsar(self, parfilename, timfilename, engine='pint', \ 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 [pint] :param testpulsar: If True, open the test pulsar (J1744, NANOGrav) """ if engine=='pint': trypint = True else: trypint = False engine, pclass = qp.get_engine(trypint=trypint) # This all is a bit ugly... 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 if dirname != '': 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 if dirname != '': 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': if not testpulsar: psr = qp.PPulsar(parfilename, timfilename) cell = "psr = qp."+pclass+"('"+parfilename+"', '"+timfilename+"')" else: psr = qp.PPulsar(testpulsar=True) cell = "psr = qp."+pclass+"(testpulsar=True)" self.kernel.shell.run_cell(cell) psr = self.kernel.shell.ns_table['user_local']['psr'] else: print("Engine = ", engine) raise NotImplemented("Only works with PINT/libstempo") # Update the plk widget self.plkWidget.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 """ 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() pass
class ConsoleManager: def __init__(self, context_provider=None): """ Args: context_provider: A callable that returns a list of InternalObjectDescriptor for variables that will be accessible from the Jupyter console. """ self._kernel_manager = None self._context_provider = context_provider or (lambda: []) self._context = None self._window = None if JUPYTER_AVAILABLE: # This is sort of experimental. Initialization of a kernel manager takes some time, # we don't want to do that in the main thread when the application is running. Do something about it. try: self._kernel_manager = self._get_kernel_manager() except Exception: logger.info('Could not initialize kernel manager', exc_info=True) # noinspection PyUnresolvedReferences def _get_context(self): # See http://ipython.readthedocs.org/en/stable/api/generated/IPython.core.interactiveshell.html if self._context is None: self._context = self._context_provider() try: import matplotlib as mpl import matplotlib.pyplot as plt self._context.append(InternalObjectDescriptor('mpl', mpl, 'Imported module "matplotlib"')) self._context.append(InternalObjectDescriptor('plt', plt, 'Imported module "matplotlib.pyplot"')) except ImportError: pass try: import numpy as np self._context.append(InternalObjectDescriptor('np', np, 'Imported module "numpy"')) except ImportError: pass try: import pylab self._context.append(InternalObjectDescriptor('pylab', pylab, 'Imported module "pylab"')) except ImportError: pass return self._context def _get_kernel_manager(self): if self._kernel_manager is None: if not JUPYTER_AVAILABLE: raise RuntimeError('Jupyter is not available on this system') # Initializing the kernel self._kernel_manager = QtInProcessKernelManager() self._kernel_manager.start_kernel() self._kernel_manager.kernel.gui = 'qt' # Initializing context self._kernel_manager.kernel.shell.push({x.name : x.object for x in self._get_context()}) return self._kernel_manager def _make_banner(self): longest_name = max([len(x.name) for x in self._get_context()]) banner = 'Available entities:\n' for obj in self._context: banner += '\t%- *s -> %s\n' % (longest_name, obj.name, obj.usage_info) banner += 'Pyuavcan docs: http://uavcan.org/Implementations/Pyuavcan\n' banner += 'DSDL reference: http://uavcan.org/Specification/7._List_of_standard_data_types\n' return banner def show_console_window(self, parent): if self._window is None: km = self._get_kernel_manager() banner = self._make_banner() def on_close(): self._window = None self._window = JupyterConsoleWindow(parent, km, banner) self._window.on_close = on_close # TODO: Jupyter takes a long time to start up, which may sometimes interfere with the node. Fix it somehow. # Here, by using the timer we can split the long start-up sequence into two shorter bursts, which kinda helps. # Ideally, the node should be running in a dedicated thread. # noinspection PyCallByClass,PyTypeChecker QTimer.singleShot(50, self._window.show) def close(self): if self._window is not None: self._window.close() self._window = None
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='pint', \ parfile=None, timfile=None, perfile=None, **kwargs): super(QtipWindow, self).__init__(parent) self.setWindowTitle('QtIpython interface to PINT/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='binary', showIPython=False, firsttime=True) self.pref_engine = engine if 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 # Also open the Binary Widget self.requestOpenBinary(testpulsar=True) # Are we going to open plk straight away? self.requestOpenPlk(testpulsar=testpulsar, parfilename=parfile, \ timfilename=timfile, engine=self.pref_engine) else: if perfile is None: testpulsar = True else: testpulsar = False if parfile is None: parfile = "" self.requestOpenBinary(testpulsar=testpulsar, parfilename=parfile, \ perfilename=perfile) 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 par/tim', self) self.openParTimAction.setShortcut('Ctrl+O') self.openParTimAction.setStatusTip('Open par/tim') self.openParTimAction.triggered.connect(self.openParTim) self.openParPerAction = QtGui.QAction('Open &par/bestprof', self) self.openParPerAction.setShortcut('Ctrl+G') self.openParPerAction.setStatusTip('Open par/bestprof files') self.openParPerAction.triggered.connect(self.openParPer) self.openPerAction = QtGui.QAction('Open &bestprof', self) self.openPerAction.setShortcut('Ctrl+H') self.openPerAction.setStatusTip('Open bestprof files') self.openPerAction.triggered.connect(self.openPer) 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.openParPerAction) self.fileMenu.addAction(self.openPerAction) 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, libfitorbit as lo" 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 = JupyterWidget() #self.consoleWidget.setMinimumSize(600, 550) # Why is there another banner showing as well? self.consoleWidget.banner = QtipBanner self.consoleWidget.kernel_manager = self.kernelManager # The client ... 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: This widget will become the first main widget to see. At the moment, however, we're avoiding it for the sake of testing purposes """ # TODO: This widget is not really used at the moment 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() == '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(50, 100) self.mainFrame.setLayout(self.hbox) self.mainFrame.show() def requestOpenBinary(self, parfilename=None, perfilename=None, \ testpulsar=False): """ Request to open a file in the binary widget @param parfilename: The parfile to open. If None, ask the user @param perfilename: The per/bestprof file to open. If None, ask user """ self.setQtipLayout(whichWidget='binary', showIPython=self.showIPython) if parfilename is None and not testpulsar: parfilename = QtGui.QFileDialog.getOpenFileName(self, 'Open par-file', '~/') elif parfilename == "": # We do not need to load a par file parfilename = None if perfilename is None and not testpulsar: perfilename = QtGui.QFileDialog.getOpenFileName(self, 'Open per/bestprof file', '~/') # Load the pulsar self.openBinaryPulsar(parfilename, perfilename, testpulsar=testpulsar) def requestOpenPlk(self, parfilename=None, timfilename=None, \ testpulsar=False, engine='pint'): """ 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.openPlkPulsar(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): """ Open a par-file and a tim-file """ # TODO: obtain the engine from elsewhere #engine='libstempo' # Ask the user for a par and tim file, and open these with libstempo/pint parfilename = QtGui.QFileDialog.getOpenFileName(self, 'Open par-file', '~/') timfilename = QtGui.QFileDialog.getOpenFileName(self, 'Open tim-file', '~/') # Load the pulsar self.openPlkPulsar(parfilename, timfilename, engine=self.pref_engine) def openParPer(self): """ Open a par-file and a per/bestprof file """ # Ask the user for a par and tim file, and open these with libstempo/pint parfilename = QtGui.QFileDialog.getOpenFileName(self, 'Open par-file', '~/') perfilename = QtGui.QFileDialog.getOpenFileName(self, 'Open per/bestprof-file', '~/') # Load the pulsar self.openBinaryPulsar(parfilename=parfilename, \ perfilename=perfilename) def openPer(self): """ Open a per/bestprof file """ # Ask the user for a par and tim file, and open these with libstempo/pint perfilename = QtGui.QFileDialog.getOpenFileName(self, 'Open per/bestprof-file', '~/') # Load the pulsar self.openBinaryPulsar(parfilename=None, perfilename=perfilename) def openPlkPulsar(self, parfilename, timfilename, engine='pint', \ 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 [pint] @param testpulsar: If True, open the test pulsar (J1744, NANOGrav) """ if engine=='pint': trypint = True else: trypint = False 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 if dirname != '': 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 if dirname != '': 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': if not testpulsar: psr = qp.PPulsar(parfilename, timfilename) cell = "psr = qp."+pclass+"('"+parfilename+"', '"+timfilename+"')" else: psr = qp.PPulsar(testpulsar=True) cell = "psr = qp."+pclass+"(testpulsar=True)" self.kernel.shell.run_cell(cell) psr = self.kernel.shell.ns_table['user_local']['psr'] else: print("Engine = ", engine) raise NotImplemented("Only works with PINT/libstempo") # Update the plk widget self.plkWidget.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 openBinaryPulsar(self, parfilename=None, perfilename=None, \ testpulsar=False): """ Open a pulsar, given a .bestprof file, and perhaps a par file @param parfilename: The name of the par/ephemeris file to open @param perfilename: The name of the .bestprof file to open @param testpulsar: If True, open the test pulsar (J1756) """ if testpulsar or perfilename is None: # Need to load the test pulsar tperfilename = tempfile.mktemp() tperfile = open(tperfilename, 'w') tperfile.write(constants.J1903PER) #tperfile.write(constants.J1756PER) tperfile.close() else: tperfilename = perfilename # Load the per-file cell = "bpsr = lo.orbitpulsar()" self.kernel.shell.run_cell(cell) cell = "bpsr.readPerFile('" + tperfilename +"')" self.kernel.shell.run_cell(cell) if testpulsar or perfilename is None: os.remove(tperfilename) if testpulsar: tparfilename = tempfile.mktemp() tparfile = open(tparfilename, 'w') tparfile.write(constants.J1903EPH) #tperfile.write(constants.J1756PER) tparfile.close() cell = "bpsr.readParFile('" + tparfilename +"')" self.kernel.shell.run_cell(cell) os.remove(tparfilename) elif parfilename is not None: cell = "bpsr.readParFile('" + parfilename +"')" self.kernel.shell.run_cell(cell) bpsr = self.kernel.shell.ns_table['user_local']['bpsr'] self.binaryWidget.setPulsar(bpsr) 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()
class ManagerGui(GUIBase): """This class provides a GUI to the Qudi manager. @signal sigStartAll: sent when all modules should be loaded @signal str str sigStartThis: load a specific module @signal str str sigReloadThis reload a specific module from Python code @signal str str sigStopThis: stop all actions of a module and remove references It supports module loading, reloading, logging and other administrative tasks. """ # status vars consoleFontSize = StatusVar('console_font_size', 10) # signals sigStartAll = QtCore.Signal() sigStartModule = QtCore.Signal(str, str) sigReloadModule = QtCore.Signal(str, str) sigCleanupStatus = QtCore.Signal(str, str) sigStopModule = QtCore.Signal(str, str) sigLoadConfig = QtCore.Signal(str, bool) sigSaveConfig = QtCore.Signal(str) sigRealQuit = QtCore.Signal() def __init__(self, **kwargs): """Create an instance of the module. @param object manager: @param str name: @param dict config: """ super().__init__(**kwargs) self.modlist = list() self.modules = set() def on_activate(self): """ Activation method called on change to active state. This method creates the Manager main window. """ if _has_pyqtgraph: # set background of pyqtgraph testwidget = QWidget() testwidget.ensurePolished() bgcolor = testwidget.palette().color(QPalette.Normal, testwidget.backgroundRole()) # set manually the background color in hex code according to our # color scheme: pg.setConfigOption('background', bgcolor) # opengl usage if 'useOpenGL' in self._manager.tree['global']: pg.setConfigOption('useOpenGL', self._manager.tree['global']['useOpenGL']) self._mw = ManagerMainWindow() self.restoreWindowPos(self._mw) self.errorDialog = ErrorDialog(self) self._about = AboutDialog() version = self.getSoftwareVersion() configFile = self._manager.configFile self._about.label.setText( '<a href=\"https://github.com/Ulm-IQO/qudi/commit/{0}\"' ' style=\"color: cyan;\"> {0} </a>, on branch {1}.'.format( version[0], version[1])) self.versionLabel = QtWidgets.QLabel() self.versionLabel.setText( '<a href=\"https://github.com/Ulm-IQO/qudi/commit/{0}\"' ' style=\"color: cyan;\"> {0} </a>,' ' on branch {1}, configured from {2}'.format( version[0], version[1], configFile)) self.versionLabel.setOpenExternalLinks(True) self._mw.statusBar().addWidget(self.versionLabel) # Connect up the buttons. self._mw.actionQuit.triggered.connect(self._manager.quit) self._mw.actionLoad_configuration.triggered.connect(self.getLoadFile) self._mw.actionReload_current_configuration.triggered.connect(self.reloadConfig) self._mw.actionSave_configuration.triggered.connect(self.getSaveFile) self._mw.action_Load_all_modules.triggered.connect(self._manager.startAllConfiguredModules) self._mw.actionAbout_Qt.triggered.connect(QtWidgets.QApplication.aboutQt) self._mw.actionAbout_Qudi.triggered.connect(self.showAboutQudi) self._mw.actionReset_to_default_layout.triggered.connect(self.resetToDefaultLayout) self._manager.sigShowManager.connect(self.show) self._manager.sigConfigChanged.connect(self.updateConfigWidgets) self._manager.sigModulesChanged.connect(self.updateConfigWidgets) self._manager.sigShutdownAcknowledge.connect(self.promptForShutdown) # Log widget self._mw.logwidget.setManager(self._manager) for loghandler in logging.getLogger().handlers: if isinstance(loghandler, core.logger.QtLogHandler): loghandler.sigLoggedMessage.connect(self.handleLogEntry) # Module widgets self.sigStartModule.connect(self._manager.startModule) self.sigReloadModule.connect(self._manager.restartModuleRecursive) self.sigCleanupStatus.connect(self._manager.removeStatusFile) self.sigStopModule.connect(self._manager.deactivateModule) self.sigLoadConfig.connect(self._manager.loadConfig) self.sigSaveConfig.connect(self._manager.saveConfig) self.sigRealQuit.connect(self._manager.realQuit) # Module state display self.checkTimer = QtCore.QTimer() self.checkTimer.start(1000) self.updateGUIModuleList() # IPython console widget self.startIPython() self.updateIPythonModuleList() self.startIPythonWidget() # thread widget self._mw.threadWidget.threadListView.setModel(self._manager.tm) # remote widget # hide remote menu item if rpyc is not available self._mw.actionRemoteView.setVisible(self._manager.rm is not None) if (self._manager.rm is not None): self._mw.remoteWidget.remoteModuleListView.setModel(self._manager.rm.remoteModules) if (self._manager.remote_server): self._mw.remoteWidget.hostLabel.setText('Server URL:') self._mw.remoteWidget.portLabel.setText( 'rpyc://{0}:{1}/'.format(self._manager.rm.server.host, self._manager.rm.server.port)) self._mw.remoteWidget.sharedModuleListView.setModel( self._manager.rm.sharedModules) else: self._mw.remoteWidget.hostLabel.setVisible(False) self._mw.remoteWidget.portLabel.setVisible(False) self._mw.remoteWidget.sharedModuleListView.setVisible(False) self._mw.configDisplayDockWidget.hide() self._mw.remoteDockWidget.hide() self._mw.threadDockWidget.hide() self._mw.show() def on_deactivate(self): """Close window and remove connections. """ self.stopIPythonWidget() self.stopIPython() self.checkTimer.stop() if len(self.modlist) > 0: self.checkTimer.timeout.disconnect() self.sigStartModule.disconnect() self.sigReloadModule.disconnect() self.sigStopModule.disconnect() self.sigLoadConfig.disconnect() self.sigSaveConfig.disconnect() self._mw.actionQuit.triggered.disconnect() self._mw.actionLoad_configuration.triggered.disconnect() self._mw.actionSave_configuration.triggered.disconnect() self._mw.action_Load_all_modules.triggered.disconnect() self._mw.actionAbout_Qt.triggered.disconnect() self._mw.actionAbout_Qudi.triggered.disconnect() self.saveWindowPos(self._mw) self._mw.close() def show(self): """Show the window and bring it t the top. """ QtWidgets.QMainWindow.show(self._mw) self._mw.activateWindow() self._mw.raise_() def showAboutQudi(self): """Show a dialog with details about Qudi. """ self._about.show() @QtCore.Slot(bool, bool) def promptForShutdown(self, locked, broken): """ Display a dialog, asking the user to confirm shutdown. """ text = "Some modules are locked right now, really quit?" result = QtWidgets.QMessageBox.question( self._mw, 'Qudi: Really Quit?', text, QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No ) if result == QtWidgets.QMessageBox.Yes: self.sigRealQuit.emit() def resetToDefaultLayout(self): """ Return the dockwidget layout and visibility to its default state """ self._mw.configDisplayDockWidget.setVisible(False) self._mw.consoleDockWidget.setVisible(True) self._mw.remoteDockWidget.setVisible(False) self._mw.threadDockWidget.setVisible(False) self._mw.logDockWidget.setVisible(True) self._mw.actionConfigurationView.setChecked(False) self._mw.actionConsoleView.setChecked(True) self._mw.actionRemoteView.setChecked(False) self._mw.actionThreadsView.setChecked(False) self._mw.actionLogView.setChecked(True) self._mw.configDisplayDockWidget.setFloating(False) self._mw.consoleDockWidget.setFloating(False) self._mw.remoteDockWidget.setFloating(False) self._mw.threadDockWidget.setFloating(False) self._mw.logDockWidget.setFloating(False) self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(8), self._mw.configDisplayDockWidget) self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(2), self._mw.consoleDockWidget) self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(8), self._mw.remoteDockWidget) self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(8), self._mw.threadDockWidget) self._mw.addDockWidget(QtCore.Qt.DockWidgetArea(8), self._mw.logDockWidget) def handleLogEntry(self, entry): """ Forward log entry to log widget and show an error popup if it is an error message. @param dict entry: Log entry """ self._mw.logwidget.addEntry(entry) if entry['level'] == 'error' or entry['level'] == 'critical': self.errorDialog.show(entry) def startIPython(self): """ Create an IPython kernel manager and kernel. Add modules to its namespace. """ # make sure we only log errors and above from ipython logging.getLogger('ipykernel').setLevel(logging.WARNING) self.log.debug('IPy activation in thread {0}'.format( QtCore.QThread.currentThreadId())) self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.namespace = self.kernel.shell.user_ns self.namespace.update({ 'np': np, 'config': self._manager.tree['defined'], 'manager': self._manager }) if _has_pyqtgraph: self.namespace['pg'] = pg self.updateIPythonModuleList() self.kernel.gui = 'qt4' self.log.info('IPython has kernel {0}'.format( self.kernel_manager.has_kernel)) self.log.info('IPython kernel alive {0}'.format( self.kernel_manager.is_alive())) self._manager.sigModulesChanged.connect(self.updateIPythonModuleList) def startIPythonWidget(self): """ Create an IPython console widget and connect it to an IPython kernel. """ if (_has_pyqtgraph): banner_modules = 'The numpy and pyqtgraph modules have already ' \ 'been imported as ''np'' and ''pg''.' else: banner_modules = 'The numpy module has already been imported ' \ 'as ''np''.' banner = """ This is an interactive IPython console. {0} Configuration is in 'config', the manager is 'manager' and all loaded modules are in this namespace with their configured name. View the current namespace with dir(). Go, play. """.format(banner_modules) self._mw.consolewidget.banner = banner # font size self.consoleSetFontSize(self.consoleFontSize) # settings self._csd = ConsoleSettingsDialog() self._csd.accepted.connect(self.consoleApplySettings) self._csd.rejected.connect(self.consoleKeepSettings) self._csd.buttonBox.button( QtWidgets.QDialogButtonBox.Apply).clicked.connect( self.consoleApplySettings) self._mw.actionConsoleSettings.triggered.connect(self._csd.exec_) self.consoleKeepSettings() self._mw.consolewidget.kernel_manager = self.kernel_manager self._mw.consolewidget.kernel_client = \ self._mw.consolewidget.kernel_manager.client() self._mw.consolewidget.kernel_client.start_channels() # the linux style theme which is basically the monokai theme self._mw.consolewidget.set_default_style(colors='linux') def stopIPython(self): """ Stop the IPython kernel. """ self.log.debug('IPy deactivation: {0}'.format(QtCore.QThread.currentThreadId())) self.kernel_manager.shutdown_kernel() def stopIPythonWidget(self): """ Disconnect the IPython widget from the kernel. """ self._mw.consolewidget.kernel_client.stop_channels() def updateIPythonModuleList(self): """Remove non-existing modules from namespace, add new modules to namespace, update reloaded modules """ currentModules = set() newNamespace = dict() for base in ['hardware', 'logic', 'gui']: for module in self._manager.tree['loaded'][base]: currentModules.add(module) newNamespace[module] = self._manager.tree[ 'loaded'][base][module] discard = self.modules - currentModules self.namespace.update(newNamespace) for module in discard: self.namespace.pop(module, None) self.modules = currentModules def consoleKeepSettings(self): """ Write old values into config dialog. """ self._csd.fontSizeBox.setProperty('value', self.consoleFontSize) def consoleApplySettings(self): """ Apply values from config dialog to console. """ self.consoleSetFontSize(self._csd.fontSizeBox.value()) def consoleSetFontSize(self, fontsize): self._mw.consolewidget.font_size = fontsize self.consoleFontSize = fontsize self._mw.consolewidget.reset_font() def updateConfigWidgets(self): """ Clear and refill the tree widget showing the configuration. """ self.fillTreeWidget(self._mw.treeWidget, self._manager.tree) def updateGUIModuleList(self): """ Clear and refill the module list widget """ # self.clearModuleList(self) self.fillModuleList(self._mw.guilayout, 'gui') self.fillModuleList(self._mw.logiclayout, 'logic') self.fillModuleList(self._mw.hwlayout, 'hardware') def fillModuleList(self, layout, base): """ Fill the module list widget with module widgets for defined gui modules. @param QLayout layout: layout of th module list widget where module widgest should be addad @param str base: module category to fill """ for module in self._manager.tree['defined'][base]: if module not in self._manager.tree['global']['startup']: widget = ModuleListItem(self._manager, base, module) self.modlist.append(widget) layout.addWidget(widget) widget.sigLoadThis.connect(self.sigStartModule) widget.sigReloadThis.connect(self.sigReloadModule) widget.sigDeactivateThis.connect(self.sigStopModule) widget.sigCleanupStatus.connect(self.sigCleanupStatus) self.checkTimer.timeout.connect(widget.checkModuleState) def fillTreeItem(self, item, value): """ Recursively fill a QTreeWidgeItem with the contents from a dictionary. @param QTreeWidgetItem item: the widget item to fill @param (dict, list, etc) value: value to fill in """ item.setExpanded(True) if type(value) is OrderedDict or type(value) is dict: for key in value: child = QtWidgets.QTreeWidgetItem() child.setText(0, key) item.addChild(child) self.fillTreeItem(child, value[key]) elif type(value) is list: for val in value: child = QtWidgets.QTreeWidgetItem() item.addChild(child) if type(val) is dict: child.setText(0, '[dict]') self.fillTreeItem(child, val) elif type(val) is OrderedDict: child.setText(0, '[odict]') self.fillTreeItem(child, val) elif type(val) is list: child.setText(0, '[list]') self.fillTreeItem(child, val) else: child.setText(0, str(val)) child.setExpanded(True) else: child = QtWidgets.QTreeWidgetItem() child.setText(0, str(value)) item.addChild(child) def getSoftwareVersion(self): """ Try to determine the software version in case the program is in a git repository. """ try: repo = Repo(get_main_dir()) branch = repo.active_branch rev = str(repo.head.commit) return (rev, str(branch)) except Exception as e: print('Could not get git repo because:', e) return ('unknown', -1) def fillTreeWidget(self, widget, value): """ Fill a QTreeWidget with the content of a dictionary @param QTreeWidget widget: the tree widget to fill @param dict,OrderedDict value: the dictionary to fill in """ widget.clear() self.fillTreeItem(widget.invisibleRootItem(), value) def reloadConfig(self): """ Reload the current config. """ reply = QtWidgets.QMessageBox.question( self._mw, 'Restart', 'Do you want to restart the current configuration?', QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No ) configFile = self._manager._getConfigFile() restart = (reply == QtWidgets.QMessageBox.Yes) self.sigLoadConfig.emit(configFile, restart) def getLoadFile(self): """ Ask the user for a file where the configuration should be loaded from """ defaultconfigpath = os.path.join(get_main_dir(), 'config') filename = QtWidgets.QFileDialog.getOpenFileName( self._mw, 'Load Configration', defaultconfigpath, 'Configuration files (*.cfg)')[0] if filename != '': reply = QtWidgets.QMessageBox.question( self._mw, 'Restart', 'Do you want to restart to use the configuration?', QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No ) restart = (reply == QtWidgets.QMessageBox.Yes) self.sigLoadConfig.emit(filename, restart) def getSaveFile(self): """ Ask the user for a file where the configuration should be saved to. """ defaultconfigpath = os.path.join(get_main_dir(), 'config') filename = QtWidgets.QFileDialog.getSaveFileName( self._mw, 'Save Configration', defaultconfigpath, 'Configuration files (*.cfg)')[0] if filename != '': self.sigSaveConfig.emit(filename)
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 "--console" in self.arguments() or "--ipython" in self.arguments(): # start with IPython console at bottom of application from qtconsole.rich_jupyter_widget import RichJupyterWidget from qtconsole.inprocess import QtInProcessKernelManager 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 = RichJupyterWidget() 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)
class ConsoleWidget(QtGui.QWidget): createdPlot = QtCore.Signal(object) updatedVar = QtCore.Signal() def __init__(self, parent=None): super(ConsoleWidget, self).__init__() self.variable_list = get_variables() self.vbox = QtGui.QVBoxLayout() self.setLayout(self.vbox) self.kernel_manager = None self.kernel_client = None self.kernel = None self.jupyter_widget = None self.values = [] self.display_plots = [] self.shell_vars = {} self.gm_count = {} self.letters = list(string.ascii_uppercase) self.reserved_words = ['and', 'del', 'from', 'not', 'while', 'as', 'elif', 'global', 'or', 'with', 'assert', 'else', 'if', 'pass', 'yield', 'break', 'except', 'import', 'print', 'class', 'exec', 'in', 'raise', 'continue', 'finally', 'is', 'return', 'def', 'for', 'lambda', 'try'] # Create ipython widget self.kernel_manager = QtInProcessKernelManager() self.kernel_manager.start_kernel() self.kernel = self.kernel_manager.kernel self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() self.kernel_client.execute("import vcs, cdms2", silent=True) self.jupyter_widget = RichJupyterWidget() self.jupyter_widget.kernel_manager = self.kernel_manager self.jupyter_widget.kernel_client = self.kernel_client self.jupyter_widget.exit_requested.connect(self.stop) self.jupyter_widget.executed.connect(self.codeExecuted) self.original_ns = dict(self.kernel.shell.user_ns) # Push variableList variables self.variable_list.listUpdated.connect(self.updateVariables) self.updateVariables() self.vbox.addWidget(self.jupyter_widget) def clearShellVars(self): self.gm_count = {} for key, var_dict in self.shell_vars.items(): try: self.kernel.shell.user_ns.pop(self.shell_vars[key]['canvas']) except KeyError: pass try: self.kernel.shell.user_ns.pop(self.shell_vars[key]['gm']) except KeyError: pass try: self.kernel.shell.user_ns.pop(self.shell_vars[key]['template']) except KeyError: pass for var in self.values: self.values.remove(var) try: self.kernel.shell.user_ns.pop(var) except KeyError: pass def updateVariables(self, plot=None): for var in get_variables().values: if var[0] not in self.values: self.values.append(var[0]) self.kernel.shell.push({var[0]: var[1]}) if plot and plot.variables: for var in plot.variables: try: self.kernel.shell.push({var.id: var}) except AttributeError: pass def updateCanvases(self, plot): canvas_var_label = "canvas_{0}{1}".format(plot.row + 1, self.letters[plot.col]) self.shell_vars[plot]['canvas'] = canvas_var_label self.kernel.shell.push({canvas_var_label: plot.canvas}) def updateGMS(self, plot): if plot.graphics_method: gm = plot.graphics_method.name if gm[:2] == '__': gm_prefix = vcs.graphicsmethodtype(plot.graphics_method) gm_prefix = self.fixInvalidVariables(gm_prefix) if gm_prefix not in self.gm_count.keys(): self.gm_count[gm_prefix] = 1 else: self.gm_count[gm_prefix] += 1 gm = "{0}_{1}".format(gm_prefix, self.gm_count[gm_prefix]) else: gm = self.fixInvalidVariables(gm) if gm == 'default': "{0}_default".format(vcs.graphicsmethodtype(plot.graphics_method)) self.shell_vars[plot]['gm'] = gm self.kernel.shell.push({gm: plot.graphics_method}) def updateTemplates(self, plot): if plot.template: tmp = plot.template.name tmp = self.fixInvalidVariables(tmp) if tmp == 'default': tmp = 'temp_default' self.shell_vars[plot]['template'] = tmp self.kernel.shell.push({tmp: plot.template}) def updateAllPlots(self, plots): self.clearShellVars() for plot in plots: self.shell_vars[plot] = {'canvas': '', 'template': '', 'gm': ''} if plot.name() != "(Untitled)": self.updateVariables(plot) self.updateCanvases(plot) self.updateGMS(plot) self.updateTemplates(plot) else: self.updateVariables(plot) self.updateCanvases(plot) def codeExecuted(self, *varargs): namespace = self.kernel.shell.user_ns cur_keys = set(namespace) # get last output out_dict = namespace["Out"] if out_dict: last_line = out_dict[max(out_dict)] else: last_line = None for key in cur_keys - set(self.original_ns): if key[0] == "_": continue value = namespace[key] if isinstance(value, cdms2.dataset.CdmsFile): namespace[key] = FileMetadataWrapper(value) if is_cdms_var(value): cdms_var = value() cdms_var.id = key if not self.variable_list.variable_exists(cdms_var): self.variable_list.add_variable(cdms_var) else: self.variable_list.update_variable(cdms_var, key) self.updatedVar.emit() elif is_displayplot(value) and value not in self.display_plots: self.display_plots.append(value) self.createdPlot.emit(value) if is_displayplot(last_line) and last_line not in self.display_plots: self.display_plots.append(last_line) self.createdPlot.emit(last_line) def fixInvalidVariables(self, var): var = re.sub(' +', '_', var) var = re.sub("[^a-zA-Z0-9_]+", '', var) if var in self.reserved_words or not re.match("^[a-zA-Z_]", var): var = 'cdat_' + var return var def stop(self): self.kernel_client.stop_channels() self.kernel_manager.shutdown_kernel() app.exit()
def __init__(self, main, *args, **kwargs): """ Parameters ---------- help_explorer: psyplot_gui.help_explorer.HelpExplorer or None A widget that can be used to show the documentation of an object ``*args,**kwargs`` Any other keyword argument for the :class:`qtconsole.rich_jupyter_widget.RichJupyterWidget` """ self._closed = False kernel_manager = QtInProcessKernelManager() # on windows, sys.stdout may be None when using pythonw.exe. Therefore # we just us a StringIO for security orig_stdout = sys.stdout if sys.stdout is None: sys.stdout = StreamToLogger(logger) orig_stderr = sys.stderr if sys.stderr is None: sys.stderr = StreamToLogger(logger) kernel_manager.start_kernel(show_banner=False) if ipykernel.__version__ < '5.1.1': # monkey patch to fix # https://github.com/ipython/ipykernel/issues/370 def _abort_queues(kernel): pass kernel_manager.kernel._abort_queues = _abort_queues sys.stdout = orig_stdout sys.stderr = orig_stderr kernel = kernel_manager.kernel kernel.gui = 'qt4' if not with_qt5 else 'qt' kernel_client = kernel_manager.client() if rcParams['console.start_channels']: kernel_client.start_channels() self.help_explorer = kwargs.pop('help_explorer', None) super(ConsoleWidget, self).__init__(*args, parent=main, **kwargs) self.intro_msg = dedents(""" psyplot version: %s gui version: %s The console provides you the full access to the current project and plots. To make your life easier, the following modules have been imported - %s Furthermore, each time you change the selection or the content in the plot objects viewer, the `sp` (the selection) and `mp` (all arrays) variables in the console are adjusted. To disable this behaviour, set:: >>> import psyplot_gui >>> psyplot_gui.rcParams['console.auto_set_mp'] = False >>> psyplot_gui.rcParams['console.auto_set_sp'] = False To inspect and object in the console and display it's documentation in the help explorer, type 'Ctrl + I' or a '?' after the object""") % ( psyplot.__version__, psyplot_gui.__version__, '\n - '.join('%s as %s' % t for t in modules2import)) self.kernel_manager = kernel_manager self.kernel_client = kernel_client self.run_command_in_shell( '\n'.join('import %s as %s' % t for t in modules2import)) self.exit_requested.connect(self._close_mainwindow) self.exit_requested.connect(QtCore.QCoreApplication.instance().quit) # we overwrite the short cut here because the 'Ctrl+S' shortcut is # reserved for mainwindows save action try: main.register_shortcut( self.export_action, QKeySequence( 'Ctrl+Alt+S', QKeySequence.NativeText)) except AttributeError: pass psy.Project.oncpchange.connect(self.update_mp) psy.Project.oncpchange.connect(self.update_sp) self.run_script.connect(self._run_script_in_shell) self.run_command.connect(self._run_command_in_shell) # HACK: we set the IOloop for the InProcessKernel here manually without # starting it (not necessary because QApplication has a blocking # IOLoop). However, we need this because the ZMQInteractiveShell wants # to call # loop = self.kernel.io_loop # loop.call_later(0.1, loop.stop)`` zmq_ioloop.install() self.kernel_manager.kernel.io_loop = ioloop.IOLoop.current()