97 lines
3.3 KiB
Python
97 lines
3.3 KiB
Python
|
#!/usr/bin/env python
|
||
|
"""
|
||
|
Run wxPython in a second thread.
|
||
|
|
||
|
Overview:
|
||
|
Importing this module creates a second thread and starts
|
||
|
wxPython in that thread. Its single method,
|
||
|
add_cone(), sends an event to the second thread
|
||
|
telling it to create a VTK viewer window with a cone in
|
||
|
it.
|
||
|
|
||
|
This module is meant to be imported into the standard
|
||
|
Python interpreter. It also works with Pythonwin.
|
||
|
It doesn't seem to work with IDLE (on NT anyways).
|
||
|
It should also work in a wxPython application.
|
||
|
|
||
|
Applications already running a wxPython app do not
|
||
|
need to start a second thread. In these cases,
|
||
|
viewer creates the cone windows in the current
|
||
|
thread. You can test this by running shell.py
|
||
|
that comes with wxPython, importing viewer and
|
||
|
calling add_cone.
|
||
|
|
||
|
Usage:
|
||
|
[user]$ python
|
||
|
Python 1.5.2 (#1, Sep 17 1999, 20:15:36) ...
|
||
|
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
|
||
|
>>> import viewer
|
||
|
>>> viewer.add_cone() # pop up a cone window
|
||
|
>>> a = 1
|
||
|
1
|
||
|
>>> viewer.add_cone() # create another cone window
|
||
|
|
||
|
Why would anyone do this?:
|
||
|
When using wxPython, the call to app.Mainloop() takes over
|
||
|
the thread from which it is called. This presents a
|
||
|
problem for applications that want to use the standard
|
||
|
Python command line user interface, while occasionaly
|
||
|
creating a GUI window for viewing an image, plot, etc.
|
||
|
One soultion is to mangage the GUI in a second thread.
|
||
|
|
||
|
wxPython does not behave well if windows are created in
|
||
|
a thread other than the one where wxPython was originally
|
||
|
imported. ( I assume importing wxPython initializes some
|
||
|
info in the thread). The current solution is to make the
|
||
|
original import of wxPython in the second thread and then
|
||
|
create all windows in that second thread.
|
||
|
|
||
|
Methods in the main thread can create a new window by issuing
|
||
|
events to a "catcher" window in the second thread. This
|
||
|
catcher window has event handlers that actually create the
|
||
|
new window.
|
||
|
"""
|
||
|
|
||
|
class viewer_thread:
|
||
|
def start(self):
|
||
|
""" start the GUI thread
|
||
|
"""
|
||
|
import thread,time
|
||
|
thread.start_new_thread(self.run, ())
|
||
|
|
||
|
def run(self):
|
||
|
"""
|
||
|
Note that viewer_basices is first imported ***here***.
|
||
|
This is the second thread. viewer_basics imports
|
||
|
wxPython. if we imported it at
|
||
|
the module level instead of in this function,
|
||
|
the import would occur in the main thread and
|
||
|
wxPython wouldn't run correctly in the second thread.
|
||
|
"""
|
||
|
from viewer_basics import *
|
||
|
try:
|
||
|
self.app = SecondThreadApp(0)
|
||
|
self.app.MainLoop()
|
||
|
except TypeError:
|
||
|
self.app = None
|
||
|
|
||
|
def add_cone(self):
|
||
|
"""
|
||
|
send an event to the catcher window in the
|
||
|
other thread and tell it to create a cone window.
|
||
|
"""
|
||
|
import viewer_basics
|
||
|
if self.app:
|
||
|
evt = viewer_basics.AddCone()
|
||
|
viewer_basics.wxPostEvent(self.app.catcher, evt)
|
||
|
else:
|
||
|
viewer_basics.add_cone()
|
||
|
|
||
|
viewer = viewer_thread()
|
||
|
viewer.start()
|
||
|
|
||
|
def add_cone():
|
||
|
viewer.add_cone()
|
||
|
|
||
|
|