Embedding Python

Martin __NOSPAM at rogers.com__NOSPAM__
Sat Oct 2 07:48:20 CEST 2004


Greetings,

I am new to python and wish to embed python in an 3D graphics 
application to provide application automation. The high level goal is to 
be able to drive my app from a script for batch job like behavior rather 
than via the GUI (ie. I would like to run a script and see those changes 
reflected in the GUI as if the user had clicked buttons, etc.) The 
application is written in C++ and uses QT for the GUI.

I have read the python docs on python.org and (using SWIG) have been 
able to create Python shadow wrappers around the C++ classes I want to 
allow users to have been able to call them via python scripts. This part 
works well. However in terms of embedding, I feel like I am missing 
something.

For those of you familiar with QT, you know that QT apps run in a 
single-thread (essentially). Although QT supports threads, a 
QApplication based program is (by default) single-threaded. Callbacks 
(slots in QT speak) can be hooked up based on a users actions, but these 
callbacks all run in the main program thread.

So here is my question ... What's the best way to integrate Python into 
an app such as the one I am describing.

Here's what I have though of ...

Alternative #1
Add boiler plate python embedding code (ie. Py_Initialize, 
PyRun_SimpleFile(...), Py_Finalize) in a QT callback. Unfortunately, 
since the QT app is single threaded, this will wedge up the GUI, until 
the script is done. Not good.

Alternative #2
Keep the app as a single threaded app and interpret the script piece 
meal (ie. one statement at a time) at some timed interval. Allow for GUI 
updating between statement interpreting. Unfortunately, groveling over 
the Python C API, this does not look particularly easy either and would 
more or less require cutting/pasting much of the interpreter guts in my 
app. Furthermore, incomplete statements (ie. lines ending in : ) seem to 
present a problem to PyRun_SimpleString.

Alternative #3
Split the app up so that it is broken up into 2 threads (GUI and guts). 
The interpreter would run in the gut thread and change the internal data 
store. The GUI would then have to be smart enough to update itselft.
Unfortunately, this requires major app re-architecting (something I am 
trying to avoid).

Alternative #4
Spawn an interpreter thread using multi-threaded interpreter calls. This 
would then require locking/unlocking shared resources between 
Interpreter thread and the rest of the app. It feels like if I am going 
to do this #3 may be a cleaner approach.

I am sure someone out there has done this before.

For me, the key point is that I want to add this functionality without 
disrupting the entire product. I am trying to evaluate what is 
architecturally the best approach and what will give me the most bang 
for my buck.

Any help would be appreciated.

Cheers and Thanks,

Martin






More information about the Python-list mailing list