I am trying to execute a compiled Pygame Graphical application from a Tkinter interface. However, I want the pygame interface to launch into a 800x600 Graphical frame. In the same root window below the 800x600 frame that is for the pygame application, I am looking for a way to embed either:
a xterm that launches a python executable automatically located in a subdirectory called "lib/" OR
directly call the executable located in the named "lib/" folder.
The only helpful documentation i have found on the subject is here: http://poultryandprogramming.wordpress.com/2012/10/28/embedded-terminal-in-pythontk-window/
The os.system
route is the only method I see any form of documentation for.
Is it possible to do what I want with subprocess.Popen
?
This seems to be two separate questions.
First, to directly run an executable in Python, all you need is the
subprocess
module. I don't know how you missed seeing this when you say you've seen the documentation foros.system
, because that clearly says:In particular, to run some executable in the "lib/" folder, just do this:
However, I'm guessing you really want not
lib
from the current working directory, butlib
from the directory the main script resides in, right? For that, you'll want to do something like this at script startup:… and then something like this when you launch the child:
At any rate, once you have a
Popen
object, you can check whetherp
is still running, etc., by callingpoll
every so often, or by spawning a thread to block onwait
; you can kill it by callingkill
on it; etc. The docs onPopen
objects show all the things you can do.If you'd prefer to run an xterm executable that launches the Python executable, you can do that—just pass
xterm
as the first argument, and the relevant xterm arguments as the remaining arguments.But I can't see what good that would do you. You're not trying to embed a terminal session in your window, but the game itself. When you launch a GUI app from an xterm session, it doesn't run inside the xterm window; it runs in a new window. The same thing will happen if the xterm window is embedded.
As for embedding the Pygame window in your own window, there are two ways to do that.
If you're writing the Pygame game yourself, as the
display.init
docs say:Notice that the
Popen
constructor takes anenv
argument:So, you can do this:
The problem is, what window ID do you give it? Well, the blog you posted to already has the answer. The same ID that you'd give xterm's
-into
.The blog doesn't explain how to restrict it to part of your window, but the code it refers to must. The answer is to either (a) embed a child window in the main window, and give the child window's ID to the child process, or (b) give the entire window to the child process, then have the child immediately create a sub-surface and only draw to that instead of to the whole display.
However, for the particular case of Pygame (or other SDL) apps, as opposed to xterm, setting
SDL_VIDEO_WINDOW_POS
in the environment should also work. (As far as I can tell, this isn't a documented feature of Pygame, but it is a documented feature of SDL, so it ought to be reliable.)Ultimately, you'll probably need a bit of cooperation between the two apps. Spmething like this:
Tkinter parent:
Pygame child:
If you can't modify the Pygame app, things will be trickier. You will have to create two separate windows embedded into a parent window, or two windows top-level docked together in some way. (The latter isn't as scary as it sounds in X11. Whenever one window moves, programmatically move the other one.) Either way, you then launch the Pygame app embedded in one child window, and cram the Tkinter stuff into the other. You may be able to do that all through Tkinter; you may have to make Xlib calls directly (either by
ctypes
-ing to Xlib, or by using something likepython-xlib
).