12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- """GUI support for the IPython ZeroMQ kernel - GTK toolkit support.
- """
- #-----------------------------------------------------------------------------
- # Copyright (C) 2010-2011 The IPython Development Team
- #
- # Distributed under the terms of the BSD License. The full license is in
- # the file COPYING.txt, distributed as part of this software.
- #-----------------------------------------------------------------------------
- #-----------------------------------------------------------------------------
- # Imports
- #-----------------------------------------------------------------------------
- # stdlib
- import sys
- # Third-party
- import gi
- gi.require_version ('Gdk', '3.0')
- gi.require_version ('Gtk', '3.0')
- from gi.repository import GObject, Gtk
- #-----------------------------------------------------------------------------
- # Classes and functions
- #-----------------------------------------------------------------------------
- class GTKEmbed(object):
- """A class to embed a kernel into the GTK main event loop.
- """
- def __init__(self, kernel):
- self.kernel = kernel
- # These two will later store the real gtk functions when we hijack them
- self.gtk_main = None
- self.gtk_main_quit = None
- def start(self):
- """Starts the GTK main event loop and sets our kernel startup routine.
- """
- # Register our function to initiate the kernel and start gtk
- GObject.idle_add(self._wire_kernel)
- Gtk.main()
- def _wire_kernel(self):
- """Initializes the kernel inside GTK.
- This is meant to run only once at startup, so it does its job and
- returns False to ensure it doesn't get run again by GTK.
- """
- self.gtk_main, self.gtk_main_quit = self._hijack_gtk()
- GObject.timeout_add(int(1000*self.kernel._poll_interval),
- self.iterate_kernel)
- return False
- def iterate_kernel(self):
- """Run one iteration of the kernel and return True.
- GTK timer functions must return True to be called again, so we make the
- call to :meth:`do_one_iteration` and then return True for GTK.
- """
- self.kernel.do_one_iteration()
- return True
- def stop(self):
- # FIXME: this one isn't getting called because we have no reliable
- # kernel shutdown. We need to fix that: once the kernel has a
- # shutdown mechanism, it can call this.
- self.gtk_main_quit()
- sys.exit()
- def _hijack_gtk(self):
- """Hijack a few key functions in GTK for IPython integration.
- Modifies pyGTK's main and main_quit with a dummy so user code does not
- block IPython. This allows us to use %run to run arbitrary pygtk
- scripts from a long-lived IPython session, and when they attempt to
- start or stop
- Returns
- -------
- The original functions that have been hijacked:
- - Gtk.main
- - Gtk.main_quit
- """
- def dummy(*args, **kw):
- pass
- # save and trap main and main_quit from gtk
- orig_main, Gtk.main = Gtk.main, dummy
- orig_main_quit, Gtk.main_quit = Gtk.main_quit, dummy
- return orig_main, orig_main_quit
|