-
Notifications
You must be signed in to change notification settings - Fork 282
/
show.py
153 lines (120 loc) · 4.41 KB
/
show.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# Author: Prabhu Ramachandran <prabhu[at]aero[dot]iitb[dot]ac[dot]in>
# Copyright (c) 2008, Enthought, Inc.
# License: BSD Style.
from traits.etsconfig.api import ETSConfig
from pyface.api import GUI, ApplicationWindow
from traits.api import HasTraits, Button, Any
from traitsui.api import View, Group, Item
from pyface.util import guisupport
# Globals.
# The GUI instance.
_gui = None
# The stop show instance.
_stop_show = None
def is_ui_running():
""" Returns True if the UI event loop is running.
"""
from .engine_manager import options
if options.offscreen:
return True
elif ETSConfig.toolkit == 'wx':
return guisupport.is_event_loop_running_wx()
elif ETSConfig.toolkit == 'qt4':
return guisupport.is_event_loop_running_qt4()
else:
return False
###############################################################################
# `StopShow` class.
###############################################################################
class StopShow(HasTraits):
########################################
# Traits
stop = Button('Stop interaction',
desc='if the UI interaction is to be stopped')
# Private traits.
# Stores a reference to the UI object so it can be disposed when the
# interaction is stopped.
_ui = Any
view = View(Group(Item('stop'), show_labels=False),
buttons=[], title='Control Show')
######################################################################
# `object` interface.
######################################################################
def __init__(self, **traits):
super(StopShow, self).__init__(**traits)
self._ui = self.edit_traits()
######################################################################
# Non-public interface.
######################################################################
def _stop_fired(self):
_gui.stop_event_loop()
self._ui.dispose()
def show(func=None, stop=False):
""" Start interacting with the figure.
By default, this function simply creates a GUI and starts its
event loop if needed.
If it is used as a decorator, then it may be used to decorate a
function which requires a UI. If the GUI event loop is already
running it simply runs the function. If not the event loop is
started and function is run in the toolkit's event loop. The choice
of UI is via `ETSConfig.toolkit`.
If the argument stop is set to True then it pops up a UI where the
user can stop the event loop. Subsequent calls to `show` will
restart the event loop.
**Parameters**
:stop: A boolean which specifies if a UI dialog is displayed which
allows the event loop to be stopped.
**Examples**
Here is a simple example demonstrating the use of show::
>>> from mayavi import mlab
>>> mlab.test_contour3d()
>>> mlab.show()
You can stop interaction via a simple pop up UI like so::
>>> mlab.test_contour3d()
>>> mlab.show(stop=True)
The decorator can be used like so::
>>> @mlab.show
... def do():
... mlab.test_contour3d()
...
>>> do()
The decorator can also be passed the stop argument::
>>> @mlab.show(stop=True)
... def do():
... mlab.test_contour3d()
...
>>> do()
"""
global _gui, _stop_show
if func is None:
if not is_ui_running():
g = GUI()
_gui = g
if stop:
_stop_show = StopShow()
g.start_event_loop()
return
def wrapper(*args, **kw):
"""Wrapper function to run given function inside the GUI event
loop.
"""
global _gui, _stop_show
tk = ETSConfig.toolkit
if is_ui_running():
# In this case we should not pop up the UI since we likely
# don't want to stop the mainloop.
return func(*args, **kw)
else:
g = GUI()
if tk == 'wx':
# Create a dummy app so invoke later works on wx.
a = ApplicationWindow(size=(1, 1))
GUI.invoke_later(lambda: a.close())
a.open()
GUI.invoke_later(func, *args, **kw)
_gui = g
if stop:
# Pop up the UI to stop the mainloop.
_stop_show = StopShow()
g.start_event_loop()
return wrapper