What is the best way to use PyGame (SDL) within a PyGTK application?
I'm searching for a method that allows me to have a drawing area in the GTK window and at the same time being able to manage both GTK and SDL events.
I've never attempted it myself, but hearing plenty about other people who've tried, it's not a road you want to go down.
There is the alternative of putting the gui in pygame itself. There are plenty of gui toolkits built specifically for pygame that you could use. Most of them are rather unfinished, but there are 2 big, actively maintained ones: PGU and OcempGUI. The full list on the pygame site is here.
You may be interested in this message thread. Looks like they recommend against it.
PyGame works much better when it can manage its own window, or even better, use the whole screen. GTK has flexible enough widgets to allow creation of a drawing area.
This page may help, though, if you want to try it.
There's a simple solution that might work for you.
Write the PyGTK stuff and PyGame stuff as separate applications. Then from the PyGTK application call the PyGame application, using os.system to call the PyGame application. If you need to share data between the two then either use a database, pipes or IPC.
http://faq.pygtk.org/index.py?file=faq23.042.htp&req=show mentions it all:
You need to create a drawing area and set the environment variable SDL_WINDOWID after it's realized:
import os
import gobject
import gtk
import pygame
WINX = 400
WINY = 200
window = gtk.Window()
window.connect('delete-event', gtk.main_quit)
window.set_resizable(False)
area = gtk.DrawingArea()
area.set_app_paintable(True)
area.set_size_request(WINX, WINY)
window.add(area)
area.realize()
# Force SDL to write on our drawing area
os.putenv('SDL_WINDOWID', str(area.window.xid))
# We need to flush the XLib event loop otherwise we can't
# access the XWindow which set_mode() requires
gtk.gdk.flush()
pygame.init()
pygame.display.set_mode((WINX, WINY), 0, 0)
screen = pygame.display.get_surface()
image_surface = pygame.image.load('foo.png')
screen.blit(image_surface, (0, 0))
gobject.idle_add(pygame.display.update)
window.show_all()
while gtk.event_pending():
# pygame/SDL event processing goes here
gtk.main_iteration(False)
I tried doing this myself a while ago, and I never got it to work perfectly. Actually I never got it to work at all under Windows, as it kept crashing the entire OS and I ran out of patience. I continued to use it though as it was only important it ran on Linux, and was only a small project. I'd strongly recommend you investigate alternatives. It always felt like a nasty hack, and made me feel dirty.
The Sugar project has several Activities built with PyGTK and PyGame.
They wrote a support lib to achieve this, called Sugargame. You should be able to modify it for regular PyGTK apps instead of Sugar.
Here's a chapter in Sugar's development book about how to use it.
The lib allows for communicating events between GTK and PyGame.
Enjoy!
Related
Is there any way to control where pygame creates the game screen? It seems to always create it in the same general area but not in a consistent location.
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = str(position[0]) + "," + str(position[1])
as per http://pygame.org/wiki/FrequentlyAskedQuestions
You can also just center the screen with
import pygame, os
os.environ['SDL_VIDEO_CENTERED'] = '1'
Note that these should be done before you initialize pygame in the main loop. I do it right after I import os for example. And since they are not actually part of pygame, you can probably use it elsewhere, though things like gtk and wxpython provide their own mechanisms.
Positioning of windows is not handled by the client application. It's handled by the Window manager (metacity etc.).
The SDL library on which PyGame is based does have a few environment variables which can be used to give hints to the Window manager. These are hints which the WM may ignore but it's the best you can do.
The comments over here have an example.
Is there any way to control where pygame creates the game screen? It seems to always create it in the same general area but not in a consistent location.
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = str(position[0]) + "," + str(position[1])
as per http://pygame.org/wiki/FrequentlyAskedQuestions
You can also just center the screen with
import pygame, os
os.environ['SDL_VIDEO_CENTERED'] = '1'
Note that these should be done before you initialize pygame in the main loop. I do it right after I import os for example. And since they are not actually part of pygame, you can probably use it elsewhere, though things like gtk and wxpython provide their own mechanisms.
Positioning of windows is not handled by the client application. It's handled by the Window manager (metacity etc.).
The SDL library on which PyGame is based does have a few environment variables which can be used to give hints to the Window manager. These are hints which the WM may ignore but it's the best you can do.
The comments over here have an example.
There are many questions dealing with pyglet and pygame, but what I want to know is difference in theses two, in simple terms.
Not in technical terms, not experimental features and all that.
They are both libraries, both API, both for creation of games and multimedia apps, right?
Just in plain English, for someone like me, relative begginer, who has finished course about Python in Codecademy and read Head first Python book.
Pyglet is a wrapper around OpenGL, while Pygame is wrapper around SDL.
OpenGL is primarily concerned with 3d rendering, while SDL
is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D.
PyGame is low-level library. You have to do all on your own - starting at mainloop and all functions called by mainloop. You can do it in different ways.
(And you can learn something about mainloops in Pyglet, Tkinter, PyQt, wxPython and other GUIs, not only in Python)
Pyglet is framework - it has already mainloop and you can't change it and you can't see how it works. You override functions which mainloop calls. You have to keep its rules.
I've tried pyglet and pygame and rate pygame as the best .
well maybe crazy is a bit too strong of a word, but what I am asking is if there are any window toolkits out there that don't have me do this:
class MyApp(SomeWindowClass):
I really don't want to use a library made by someone who is so obsessed with objects that he/she thinks that there should be a class for the app (which there will only be one instance of, so I don't see why anyone would want to do that extra typing)
(btw, no offense intended towards anyone who agrees with the way these libraries are set up, I just really want to know if there is anything out there with a tad bit less objects)
In general GUI toolkits rely on having some form of event loop running, the Application class in these toolkits is generally in charge of that event loop and marshaling events from the underlying window manager. Sure they could call the class EventLoopManager or something, but you need it either way so its just a naming thing then. In some cases though some toolkits who often use events can occasionally be used without them, and then you certainly dont want it to be some automatic thing.
There is PyQT.
Tkinter has one object per window/dialog, not app, and requires no classes to get something painted on the screen. It does, however, have its own main loop (like all the other GUI libraries). Obligatory Hello World:
from Tkinter import *
root = Tk()
w = Label(root, text="Hello, world!")
w.pack()
root.mainloop()
PyGTK another toolkit; which is python binding of Gtk. It is well structured with having excellent window and event loop system.
A typical example to show a window
import gtk
class Application:
def __init__(self):
self.window = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
self.window.show()
if __name__ == "__main__":
app = Application()
gtk.mainloop()
Another recommendation is PyQt; which is python binding of Qt.
Typical hello world example is
import sys
from qt import *
app = QApplication(sys.argv)
myLabel = QLabel("Hello world!", None)
app.setMainWidget(myLabel)
myLabel.show()
app.exec_loop()
PyQt and PyGtk are widely used for rapid GUI development. From my experience pyGtk is poor in the online documentation/support compared to pyQt. But both are favorite of mine.
As you see with the answers above, GUI programming is almost always heavily object oriented, and there are good reasons for this: the graphical elements share a lot in terms of how they can be positioned within one-another, caring about whether the mouse pointer is over them etc. Furthermore, the C++ kits that qt, wx, gtk et al. wrap are already structured on a class/inheritance hierarchy, so you should not be surprised that the python wrappers are also.
If you want only simple GUI elements, then you may consider easyGUI (simple message boxes, text edit, choices), triatsUI (interactive object wrappers, primarily for controlling graphical objects) , which each solve some part of the GUI interactions without explicitly having you write GUI code.
For editing the values of fields in a record-like structure, you could also investigate GUIdata.
PS: there are various graphical tools out there to let you design your GUIs and link together some of the events, e.g., QtDesigner, that can help you avoid much of the tedious class definition code.
I am working on embedded linux platform with limited system resources.
I want to do fullscreen slideshow with simple transistions (like slide in-out, fade in-out ).
I tried PyGtk+GTK+Cairo but its very slow, when I animate GTK image controls I get just two or three frames per second. But smplayer is playing video at good speed!
I did some little research and came to know about directfb, libggi, svgalib etc. and I don't know what library should be used.
Which library is the best for this kind of application? I would prefer to do this without stopping X.
I would try this first using just PyCairo, not using GTK controls at all.
However, if that does not give you the speed that you need, then you might want to try PyGame which gives you access to SDL including OpenGL backends. PyGame is very actively developed and used in building applications that include full screen animation so even if you are not writing a game, you will still likely find the best support by using PyGame.