Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Gtk3 integration with ipython works. #1588

Merged
merged 7 commits into from

3 participants

Thomi Richards Fernando Perez Thomas Kluyver
Thomi Richards

This branch adds support for interactive Gtk3 UI support.

The older Gtk2 bindings (pygtk) are being deprecated in the wild, in favor of the newer gi bindings. This allows users to use new features in Gtk3. This is a very simple branch, that follows the same pattern as the 'gtk' UI support feature, but for Gtk3.

Fernando Perez
Owner

Do you have any tests we can use to see this functionality at work? It could be an interactive example that goes into docs/examples/lib if it's hard to unittest this...

Also, since this adds a 'gtk3' target for the %gui magic, the docstring for magic_gui needs to be updated to show that gtk3 is also a valid value.

Thomi Richards

Hi,

Thanks for looking at this. Both changes have been made now. I added a docstring to the %gui magic function. I notice that the UI types weren't listed alphabetically, so I put the docstring for 'gtk3' right below the docstring or 'gtk'. As far as testing is concerned, I've followed the pattern for the 'gtk' Gui integration.

IPython/core/magic.py
@@ -94,7 +94,7 @@ def needs_local_scope(func):
func.needs_local_scope = True
return func
-
+
Thomas Kluyver Owner

For future reference: please try to avoid whitespace changes in functional pull requests, because it makes it hard to see what's really changed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
docs/examples/lib/gui-gtk3.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+"""Simple Gtk example to manually test event loop integration.
+
+This is meant to run tests manually in ipython as:
+
+In [1]: %gui gtk3
+
+In [2]: %run gui-gtk3.py
+"""
+
+from gi.repository import Gtk
+
+
+def hello_world(wigdet, data=None):
+ print "Hello World"
Thomas Kluyver Owner

Can you change this to print("Hello World") so it's easy to test from Python 3 (I've just done it locally, and it does work). The brackets are valid in Python 2 for a single argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Fernando Perez
Owner

@thomir, it seems that (in addition to the small fix suggested by @takluyver), this PR now has a conflict with master, likelye something small that's colliding with other recently merged code. We'll have to ask you to rebase it before we can merge it, unfortunately.

Let us know if you need help with that and we'll give you a hand. Once you rebase and make that small fix I'll take care of merging it quickly so this doesn't happen again.

Thomas Kluyver
Owner

It may well be the whitespace changes conflicting with a change in nearby lines.

Fernando Perez
Owner

Yes, very likely, though I haven't confirmed yet by looking at the conflicts.

Thomi Richards

Hi,

Sorry about the whitespace changes - my editor automatically strips trailing whitespace, so I didn't even notice I had done this.

I've merged trunk, and fixed the conflicts. I think I've done this correctly, although I'm using the git backend to bzr, so there's a chance it's not correct.

Thanks again for looking at this.

IPython/core/magic.py
((13 lines not shown))
contents = openpy.read_py_file(arg_s, skip_encoding_cookie=True)
self.set_next_input(contents)
+>>>>>>> MERGE-SOURCE
Thomas Kluyver Owner

Nope, this merge didn't quite go right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Thomas Kluyver
Owner

The docstring change for the %gui magic seems to have gone missing after the latest merge.

Thomi Richards

OK, I figured out how to use rebase properly :)

Thomi Richards

whitespace-only changes reverted.

Thomas Kluyver takluyver merged commit 9096723 into from
Thomas Kluyver
Owner

@fperez already OKed the changes, so I've merged this.

Fernando Perez
Owner

Many thanks to all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
1  IPython/core/magic.py
View
@@ -3420,6 +3420,7 @@ def magic_gui(self, parameter_s=''):
%gui wx # enable wxPython event loop integration
%gui qt4|qt # enable PyQt4 event loop integration
%gui gtk # enable PyGTK event loop integration
+ %gui gtk3 # enable Gtk3 event loop integration
%gui tk # enable Tk event loop integration
%gui OSX # enable Cocoa event loop integration
# (requires %matplotlib 1.1)
1  IPython/lib/__init__.py
View
@@ -21,6 +21,7 @@
enable_tk, disable_tk,
enable_glut, disable_glut,
enable_pyglet, disable_pyglet,
+ enable_gtk3, disable_gtk3,
set_inputhook, clear_inputhook,
current_gui
)
31 IPython/lib/inputhook.py
View
@@ -36,6 +36,7 @@
GUI_OSX = 'osx'
GUI_GLUT = 'glut'
GUI_PYGLET = 'pyglet'
+GUI_GTK3 = 'gtk3'
GUI_NONE = 'none' # i.e. disable
#-----------------------------------------------------------------------------
@@ -421,6 +422,33 @@ def disable_pyglet(self):
"""
self.clear_inputhook()
+ def enable_gtk3(self, app=None):
+ """Enable event loop integration with Gtk3 (gir bindings).
+
+ Parameters
+ ----------
+ app : ignored
+ Ignored, it's only a placeholder to keep the call signature of all
+ gui activation methods consistent, which simplifies the logic of
+ supporting magics.
+
+ Notes
+ -----
+ This methods sets the PyOS_InputHook for Gtk3, which allows
+ the Gtk3 to integrate with terminal based applications like
+ IPython.
+ """
+ from IPython.lib.inputhookgtk3 import inputhook_gtk3
+ self.set_inputhook(inputhook_gtk3)
+ self._current_gui = GUI_GTK
+
+ def disable_gtk3(self):
+ """Disable event loop integration with PyGTK.
+
+ This merely sets PyOS_InputHook to NULL.
+ """
+ self.clear_inputhook()
+
def current_gui(self):
"""Return a string indicating the currently active GUI or None."""
return self._current_gui
@@ -439,6 +467,8 @@ def current_gui(self):
disable_glut = inputhook_manager.disable_glut
enable_pyglet = inputhook_manager.enable_pyglet
disable_pyglet = inputhook_manager.disable_pyglet
+enable_gtk3 = inputhook_manager.enable_gtk3
+disable_gtk3 = inputhook_manager.disable_gtk3
clear_inputhook = inputhook_manager.clear_inputhook
set_inputhook = inputhook_manager.set_inputhook
current_gui = inputhook_manager.current_gui
@@ -480,6 +510,7 @@ def enable_gui(gui=None, app=None):
GUI_QT4: enable_qt4,
GUI_GLUT: enable_glut,
GUI_PYGLET: enable_pyglet,
+ GUI_GTK3: enable_gtk3,
}
try:
gui_hook = guis[gui]
34 IPython/lib/inputhookgtk3.py
View
@@ -0,0 +1,34 @@
+# encoding: utf-8
+"""
+Enable Gtk3 to be used interacive by IPython.
+
+Authors: Thomi Richards
+"""
+#-----------------------------------------------------------------------------
+# Copyright (c) 2012, the IPython Development Team.
+#
+# Distributed under the terms of the Modified BSD License.
+#
+# The full license is in the file COPYING.txt, distributed with this software.
+#-----------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------
+# Imports
+#-----------------------------------------------------------------------------
+
+import sys
+from gi.repository import Gtk, GLib
+
+#-----------------------------------------------------------------------------
+# Code
+#-----------------------------------------------------------------------------
+
+def _main_quit(*args, **kwargs):
+ Gtk.main_quit()
+ return False
+
+
+def inputhook_gtk3():
+ GLib.io_add_watch(sys.stdin, GLib.IO_IN, _main_quit)
+ Gtk.main()
+ return 0
37 docs/examples/lib/gui-gtk3.py
View
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+"""Simple Gtk example to manually test event loop integration.
+
+This is meant to run tests manually in ipython as:
+
+In [1]: %gui gtk3
+
+In [2]: %run gui-gtk3.py
+"""
+
+from gi.repository import Gtk
+
+
+def hello_world(wigdet, data=None):
+ print("Hello World")
+
+def delete_event(widget, event, data=None):
+ return False
+
+def destroy(widget, data=None):
+ Gtk.main_quit()
+
+window = Gtk.Window(Gtk.WindowType.TOPLEVEL)
+window.connect("delete_event", delete_event)
+window.connect("destroy", destroy)
+button = Gtk.Button("Hello World")
+button.connect("clicked", hello_world, None)
+
+window.add(button)
+button.show()
+window.show()
+
+try:
+ from IPython.lib.inputhook import enable_gtk3
+ enable_gtk3()
+except ImportError:
+ Gtk.main()
Something went wrong with that request. Please try again.