##// END OF EJS Templates
Fixing wx related issue in guisupport.py.
Brian Granger -
Show More
@@ -1,145 +1,147 b''
1 1 #!/usr/bin/env python
2 2 # coding: utf-8
3 3 """
4 4 Support for creating GUI apps and starting event loops.
5 5
6 6 IPython's GUI integration allows interative plotting and GUI usage in IPython
7 7 session. IPython has two different types of GUI integration:
8 8
9 9 1. The terminal based IPython supports GUI event loops through Python's
10 10 PyOS_InputHook. PyOS_InputHook is a hook that Python calls periodically
11 11 whenever raw_input is waiting for a user to type code. We implement GUI
12 12 support in the terminal by setting PyOS_InputHook to a function that
13 13 iterates the event loop for a short while. It is important to note that
14 14 in this situation, the real GUI event loop is NOT run in the normal
15 15 manner, so you can't use the normal means to detect that it is running.
16 16 2. In the two process IPython kernel/frontend, the GUI event loop is run in
17 17 the kernel. In this case, the event loop is run in the normal manner by
18 18 calling the function or method of the GUI toolkit that starts the event
19 19 loop.
20 20
21 21 In addition to starting the GUI event loops in one of these two ways, IPython
22 22 will *always* create an appropriate GUI application object when GUi
23 23 integration is enabled.
24 24
25 25 If you want your GUI apps to run in IPython you need to do two things:
26 26
27 27 1. Test to see if there is already an existing main application object. If
28 28 there is, you should use it. If there is not an existing application object
29 29 you should create one.
30 30 2. Test to see if the GUI event loop is running. If it is, you should not
31 31 start it. If the event loop is not running you may start it.
32 32
33 33 This module contains functions for each toolkit that perform these things
34 34 in a consistent manner. Because of how PyOS_InputHook runs the event loop
35 35 you cannot detect if the event loop is running using the traditional calls
36 36 (such as ``wx.GetApp.IsMainLoopRunning()`` in wxPython). If PyOS_InputHook is
37 37 set These methods will return a false negative. That is, they will say the
38 38 event loop is not running, when is actually is. To work around this limitation
39 39 we proposed the following informal protocol:
40 40
41 41 * Whenever someone starts the event loop, they *must* set the ``_in_event_loop``
42 42 attribute of the main application object to ``True``. This should be done
43 43 regardless of how the event loop is actually run.
44 44 * Whenever someone stops the event loop, they *must* set the ``_in_event_loop``
45 45 attribute of the main application object to ``False``.
46 46 * If you want to see if the event loop is running, you *must* use ``hasattr``
47 47 to see if ``_in_event_loop`` attribute has been set. If it is set, you
48 48 *must* use its value. If it has not been set, you can query the toolkit
49 49 in the normal manner.
50 50 * If you want GUI support and no one else has created an application or
51 51 started the event loop you *must* do this. We don't want projects to
52 52 attempt to defer these things to someone else if they themselves need it.
53 53
54 54 The functions below implement this logic for each GUI toolkit. If you need
55 55 to create custom application subclasses, you will likely have to modify this
56 56 code for your own purposes. This code can be copied into your own project
57 57 so you don't have to depend on IPython.
58 58
59 59 """
60 60
61 61 #-----------------------------------------------------------------------------
62 62 # Copyright (C) 2008-2010 The IPython Development Team
63 63 #
64 64 # Distributed under the terms of the BSD License. The full license is in
65 65 # the file COPYING, distributed as part of this software.
66 66 #-----------------------------------------------------------------------------
67 67
68 68 #-----------------------------------------------------------------------------
69 69 # Imports
70 70 #-----------------------------------------------------------------------------
71 71
72 72 #-----------------------------------------------------------------------------
73 73 # wx
74 74 #-----------------------------------------------------------------------------
75 75
76 76 def get_app_wx(*args, **kwargs):
77 77 """Create a new wx app or return an exiting one."""
78 78 import wx
79 79 app = wx.GetApp()
80 80 if app is None:
81 if not kwargs.has_key('redirect'):
82 kwargs['redirect'] = False
81 83 app = wx.PySimpleApp(*args, **kwargs)
82 84 return app
83 85
84 86 def is_event_loop_running_wx(app=None):
85 87 """Is the wx event loop running."""
86 88 if app is None:
87 89 app = get_app_wx()
88 90 if hasattr(app, '_in_event_loop'):
89 91 return app._in_event_loop
90 92 else:
91 93 return app.IsMainLoopRunning()
92 94
93 95 def start_event_loop_wx(app=None):
94 96 """Start the wx event loop in a consistent manner."""
95 97 if app is None:
96 98 app = get_app_wx()
97 99 if not is_event_loop_running_wx(app):
98 100 app._in_event_loop = True
99 101 app.MainLoop()
100 102 app._in_event_loop = False
101 103 else:
102 104 app._in_event_loop = True
103 105
104 106 #-----------------------------------------------------------------------------
105 107 # qt4
106 108 #-----------------------------------------------------------------------------
107 109
108 110 def get_app_qt4(*args, **kwargs):
109 111 """Create a new qt4 app or return an existing one."""
110 112 from PyQt4 import QtGui
111 113 app = QtGui.QApplication.instance()
112 114 if app is None:
113 115 if not args:
114 116 args = ([''],)
115 117 app = QtGui.QApplication(*args, **kwargs)
116 118 return app
117 119
118 120 def is_event_loop_running_qt4(app=None):
119 121 """Is the qt4 event loop running."""
120 122 if app is None:
121 123 app = get_app_qt4([''])
122 124 if hasattr(app, '_in_event_loop'):
123 125 return app._in_event_loop
124 126 else:
125 127 # Does qt4 provide a other way to detect this?
126 128 return False
127 129
128 130 def start_event_loop_qt4(app=None):
129 131 """Start the qt4 event loop in a consistent manner."""
130 132 if app is None:
131 133 app = get_app_qt4([''])
132 134 if not is_event_loop_running_qt4(app):
133 135 app._in_event_loop = True
134 136 app.exec_()
135 137 app._in_event_loop = False
136 138 else:
137 139 app._in_event_loop = True
138 140
139 141 #-----------------------------------------------------------------------------
140 142 # Tk
141 143 #-----------------------------------------------------------------------------
142 144
143 145 #-----------------------------------------------------------------------------
144 146 # gtk
145 147 #-----------------------------------------------------------------------------
General Comments 0
You need to be logged in to leave comments. Login now