[python-win32] Starting a GUI app from AddIn server
Johannes Brunen
jbrunen at datasolid.de
Wed Mar 22 08:30:12 CET 2006
Hi,
I'm facing the following problem:
I have written an AddIn server which is called from a GUI application.
After some action in the GUI app the function
DoSomething of class CmdEvtHandlerStartApp is called. This works pretty
fine.
class AddInBase:
"""
Base class for CADdy++ AddIns.
"""
_com_interfaces_ = ['ICADdyAddIn']
_public_methods_ = []
_reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER
_reg_policy_spec_ = "win32com.server.policy.EventHandlerPolicy"
_typelib_guid_ = '{9C3BB401-114D-11D4-AC72-00105A4925FC}'
....
class AddIn(AddInBase):
_reg_clsid_ = '{FC76E6CC-B0C8-4233-AFFA-45594501A4F0}'
_reg_progid_ = 'CADdyAddIn.PythonGui0'
def __init__(self):
AddInBase.__init__(self)
def OnInit(self, theCADdy):
NewCmd = self.AddCmd(NewPool, "StartGuiApplication",
constants.CMD_NOBREAK, CmdEvtHandlerStartApp)
class CmdEvtHandlerStartApp(CmdEvtHandlerBase):
def OnExecute(self, cmd, data, cmdStr):
self.DoSomething()
def DoSomething(self):
....
Now, I would like to start a separate wxPython GUI app/dialog
(wxAppGui0) from the DoSomething call which
should run asynchronously to the main GUI app. The following
requirements should be met:
1. The app/dialog should always stay on top of the main GUI app
2. The app/dialog should not appear on the window taskbar
3. The main GUI should not be affected by the app/dialog
4. I need some communication between the AddIn class and the
app/dialog
I tried the following with varying success:
a) Idee: Use a separate thread for the app/dialog and use proper locking
for data exchange between the threads.
def DoSomething(self):
import threading
import wxAppGui0
thread = threading.Thread(target = wxAppGui0.main)
thread.start()
=> This seems to work fine for a first call to the DoSomething
function. But after closing the wxAppGui0 app/dialog it is
impossible to restart the app/dialog by a new call to function
DoSomething. Inside wxPython the call to the embedded
function CreateWindowEx failed:
File
"C:\Programme\Python\Lib\site-packages\wx-2.6-msw-ansi\wx\_controls.py",
line 79, in __init__
newobj = _controls_.new_Button(*args, **kwargs)
PyAssertionError: C++ assertion "wxAssertFailure" failed
in ..\..\src\msw\control.cpp(162):
CreateWindowEx("BUTTON", flags=56010000,
ex=00000000) failed
This problem only appears if I have set the wxFrame style to
wx.FRAME_NO_TASKBAR. Is there anything I could do
in order to use this case? Is this the recommended way to go?
Are there any additionl flaws with this design?
b) Idee: Create a completly separate process for the app/dialog and
setup some communication infrastructure.
def DoSomething(self):
cmd =
r'C:\Development\Learn\Python\COM\Test\Lesson3\wxAppGui0.pyw'
import win32process
procHandle, threadHandle, procId, threadId =
win32process.CreateProcess(
None, # appName
'pythonw.exe ' + cmd,
None, # process security
None, # thread security
0, # inherit handles
win32process.NORMAL_PRIORITY_CLASS,
None, # new environment
None, # Current directory
win32process.STARTUPINFO(), # startup info
)
=> For this scenario I have to build additional communication
infrastructure (COM or pipes). I would like to avoid additional
registering of a wxAppGui0 COM server. Another problem is that I
do have to explicitly specify the wxAppGui0.pyw path.
For a) and b), additionally, I don't know how to force the app/dialog
always to be on top of the GUI app. How can I enforce
this requirement? Can I somehow tell wxPython to use my GUI application
as it's parent?
Could someone recommend a design for the above use case? I don't have
much experiences in the field.
Best
Johannes
____________
Virus checked by G DATA AntiVirusKit
Version: AVK 16.5392 from 08.02.2006
Virus news: www.antiviruslab.com
More information about the Python-win32
mailing list