inputhook.py
171 lines
| 5.8 KiB
| text/x-python
|
PythonLexer
Brian Granger
|
r2066 | #!/usr/bin/env python | |
# encoding: utf-8 | |||
""" | |||
Inputhook management for GUI event loop integration. | |||
""" | |||
#----------------------------------------------------------------------------- | |||
# Copyright (C) 2008-2009 The IPython Development Team | |||
# | |||
# Distributed under the terms of the BSD License. The full license is in | |||
# the file COPYING, distributed as part of this software. | |||
#----------------------------------------------------------------------------- | |||
#----------------------------------------------------------------------------- | |||
# Imports | |||
#----------------------------------------------------------------------------- | |||
import ctypes | |||
#----------------------------------------------------------------------------- | |||
# Code | |||
#----------------------------------------------------------------------------- | |||
class InputHookManager(object): | |||
Brian Granger
|
r2069 | """Manage PyOS_InputHook for different GUI toolkits.""" | |
Brian Granger
|
r2066 | ||
def __init__(self): | |||
self.PYFUNC = ctypes.PYFUNCTYPE(ctypes.c_int) | |||
self._reset() | |||
def _reset(self): | |||
self._callback_pyfunctype = None | |||
self._callback = None | |||
self._installed = False | |||
def get_pyos_inputhook(self): | |||
Brian Granger
|
r2069 | """Return the current PyOS_InputHook as a ctypes.c_void_p. | |
""" | |||
Brian Granger
|
r2066 | return ctypes.c_void_p.in_dll(ctypes.pythonapi,"PyOS_InputHook") | |
def get_pyos_inputhook_as_func(self): | |||
Brian Granger
|
r2069 | """Return the current PyOS_InputHook as a ctypes.PYFUNCYPE. | |
""" | |||
Brian Granger
|
r2066 | return self.PYFUNC.in_dll(ctypes.pythonapi,"PyOS_InputHook") | |
Brian Granger
|
r2069 | def set_inputhook(self, callback): | |
Brian Granger
|
r2066 | """Set PyOS_InputHook to callback and return the previous one. | |
""" | |||
self._callback = callback | |||
self._callback_pyfunctype = self.PYFUNC(callback) | |||
pyos_inputhook_ptr = self.get_pyos_inputhook() | |||
original = self.get_pyos_inputhook_as_func() | |||
pyos_inputhook_ptr.value = \ | |||
ctypes.cast(self._callback_pyfunctype, ctypes.c_void_p).value | |||
self._installed = True | |||
return original | |||
def clear_inputhook(self): | |||
Brian Granger
|
r2069 | """Set PyOS_InputHook to NULL and return the previous one. | |
""" | |||
Brian Granger
|
r2066 | pyos_inputhook_ptr = self.get_pyos_inputhook() | |
original = self.get_pyos_inputhook_as_func() | |||
pyos_inputhook_ptr.value = ctypes.c_void_p(None).value | |||
self._reset() | |||
return original | |||
def enable_wx(self): | |||
Brian Granger
|
r2069 | """Enable event loop integration with wxPython. | |
This methods sets the PyOS_InputHook for wxPython, which allows | |||
the wxPython to integrate with terminal based applications like | |||
IPython. | |||
Once this has been called, you can use wx interactively by doing:: | |||
>>> import wx | |||
>>> app = wx.App(redirect=False, clearSigInt=False) | |||
Both options this constructor are important for things to work | |||
properly in an interactive context. | |||
But, *don't start the event loop*. That is handled automatically by | |||
PyOS_InputHook. | |||
""" | |||
Brian Granger
|
r2068 | from IPython.lib.inputhookwx import inputhook_wx | |
Brian Granger
|
r2066 | self.set_inputhook(inputhook_wx) | |
def disable_wx(self): | |||
Brian Granger
|
r2069 | """Disable event loop integration with wxPython. | |
This merely sets PyOS_InputHook to NULL. | |||
""" | |||
Brian Granger
|
r2066 | self.clear_inputhook() | |
def enable_qt4(self): | |||
Brian Granger
|
r2069 | """Enable event loop integration with PyQt4. | |
This methods sets the PyOS_InputHook for wxPython, which allows | |||
the PyQt4 to integrate with terminal based applications like | |||
IPython. | |||
Once this has been called, you can simply create a QApplication and | |||
use it. But, *don't start the event loop*. That is handled | |||
automatically by PyOS_InputHook. | |||
""" | |||
Brian Granger
|
r2066 | from PyQt4 import QtCore | |
# PyQt4 has had this since 4.3.1. In version 4.2, PyOS_InputHook | |||
# was set when QtCore was imported, but if it ever got removed, | |||
# you couldn't reset it. For earlier versions we can | |||
# probably implement a ctypes version. | |||
try: | |||
QtCore.pyqtRestoreInputHook() | |||
except AttributeError: | |||
pass | |||
def disable_qt4(self): | |||
Brian Granger
|
r2069 | """Disable event loop integration with PyQt4. | |
This merely sets PyOS_InputHook to NULL. | |||
""" | |||
Brian Granger
|
r2066 | self.clear_inputhook() | |
def enable_gtk(self): | |||
Brian Granger
|
r2069 | """Enable event loop integration with PyGTK. | |
This methods sets the PyOS_InputHook for PyGTK, which allows | |||
the PyGTK to integrate with terminal based applications like | |||
IPython. | |||
Once this has been called, you can simple create PyGTK objects and | |||
use them. But, *don't start the event loop*. That is handled | |||
automatically by PyOS_InputHook. | |||
""" | |||
Brian Granger
|
r2066 | import gtk | |
try: | |||
gtk.set_interactive(True) | |||
except AttributeError: | |||
# For older versions of gtk, use our own ctypes version | |||
Brian Granger
|
r2068 | from IPython.lib.inputhookgtk import inputhook_gtk | |
Brian Granger
|
r2066 | add_inputhook(inputhook_gtk) | |
def disable_gtk(self): | |||
Brian Granger
|
r2069 | """Disable event loop integration with PyGTK. | |
This merely sets PyOS_InputHook to NULL. | |||
""" | |||
Brian Granger
|
r2066 | self.clear_inputhook() | |
def enable_tk(self): | |||
# Creating a Tkinter.Tk object sets PyOS_InputHook() | |||
pass | |||
def disable_tk(self): | |||
Brian Granger
|
r2069 | """Disable event loop integration with Tkinter. | |
This merely sets PyOS_InputHook to NULL. | |||
""" | |||
Brian Granger
|
r2066 | self.clear_inputhook() | |
inputhook_manager = InputHookManager() | |||
enable_wx = inputhook_manager.enable_wx | |||
disable_wx = inputhook_manager.disable_wx | |||
enable_qt4 = inputhook_manager.enable_qt4 | |||
disable_qt4 = inputhook_manager.disable_qt4 | |||
enable_gtk = inputhook_manager.enable_gtk | |||
disable_gtk = inputhook_manager.disable_gtk | |||
Brian Granger
|
r2068 | enable_tk = inputhook_manager.enable_tk | |
Brian Granger
|
r2069 | disable_tk = inputhook_manager.disable_tk | |
clear_inputhook = inputhook_manager.clear_inputhook | |||
set_inputhook = inputhook_manager.set_inputhook |