[Tutor] Pygame and TkInter

eryksun eryksun at gmail.com
Mon Sep 10 03:45:42 CEST 2012


On Sun, Sep 9, 2012 at 5:58 PM, Greg Nielsen <gollumgreg407366 at gmail.com> wrote:
> Hello Tutor,
>
>      Quick question. Working on a new game and want to build in a GUI.
> TkInter seems to fit the bill except for one small item. Both Pygame and
> TkInter create windows. (Screen in Pygame, and the Root widget in TkInter)
> Is there a way to combined these two so I can use all my Pygame sprites and
> objects and any TkInter bars and buttons all in one screen? My best guess
> would be something along this line.

I found this answer on Stack Overflow:

http://stackoverflow.com/questions/8584272/using-pygame-features-in-tkinter

It depends on initializing the SDL engine to use the window ID from a
Tk frame, based on the 'SDL_WINDOWID' environment variable.

I added a check of sys.platform == "win32" for the suggested use of
'SDL_VIDEODRIVER' on Windows, but I haven't verified that this is
required or that it works.

Instead of a while loop that manually pumps both SDL and Tk, I
switched to using the Tk mainloop. The frame's "after" method is used
to run pygame_loop every 5 ms, which updates the screen. You'll have
to experiment with how this affects pygame's ability to grab
keyboard/click events. You might have to use Tk for input instead.

Just to show the event loop in action, I added two buttons to
increment/decrement the current step size, tied to the incr_step
method.


    import sys
    import os
    import Tkinter as tkinter
    import pygame

    class Game(object):
        def __init__(self, root, w, h):
            self.root = root
            self.width = w
            self.height = h

            # Tk init
            self.frame = tkinter.Frame(root, width=w, height=h)
            self.frame.grid(row=0, columnspan=2)
            self.button1 = tkinter.Button(
                root, text='-', command=lambda: self.incr_step(-1))
            self.button1.grid(row=1, column=0)
            self.button2 = tkinter.Button(
                root, text='+', command=lambda: self.incr_step(1))
            self.button2.grid(row=1, column=1)
            root.update()

            # pygame init
            os.environ['SDL_WINDOWID'] = str(self.frame.winfo_id())
            if sys.platform == "win32":
                os.environ['SDL_VIDEODRIVER'] = 'windib'
            pygame.display.init()
            self.screen = pygame.display.set_mode((w, h))
            self.bg_color = pygame.Color(0,0,0)
            self.fg_color = pygame.Color(255,255,255)
            self.position = 0
            self.step = 1

            self.game_loop()

        def game_loop(self):
            self.screen.fill(self.bg_color)
            self.position = (self.position + self.step) % self.width
            coord = self.position, self.height // 2
            pygame.draw.circle(self.screen, self.fg_color, coord, 20)
            pygame.display.flip()

            self.frame.after(5, self.game_loop)

        def incr_step(self, inc):
            self.step += inc

    if __name__ == "__main__":
        root = tkinter.Tk()
        game = Game(root, 200, 200)
        root.mainloop()


More information about the Tutor mailing list