I'm embedding a pygame window into Tkinter, how do I manipulate the pygame window? I'm embedding a pygame window into Tkinter, how do I manipulate the pygame window? tkinter tkinter

I'm embedding a pygame window into Tkinter, how do I manipulate the pygame window?


So - besides the obvious missing call to pygame.display.flip - which I suppose is what you intended with the call to pygame.display.init (pygame.init already calls that one) - what I found out is that tkinter needs to initialize its windows and widgets before the packed frame is fully available to be used by Pygame.

I did that by adding a call to self.root.update_idletasks() before calling pygame.init -- that, and explicitly setting the video driver for my platform (which you already does for Windows), made things work.

Anyway, also, in your code you did not show were you wanted to make the calls to Pygamedrawing functions - as it is, it is well possible that everything is correct, but the code after screen.window() is just never run (or rather, just run at program exit) - because you call tkinter.mainloop inside the __init__ method of your application class.

Moving the call to mainloop outside the __init__ is a good practice, so you can initialize other objects and resources as well - and you actualy do have the screen object to operate things on. By making that call inside __init__ is like your whole program was running "inside the initialization".

In short:

  • call tkinter.update_iddletasks() before initializing pygame
  • remember to call pygame.display.flip after you draw anything with Pygame
  • arrange your code so that your drawing calls are actually executed, and not blocked after the call to enter tkinter's loop
  • You should seriously consider using Python 3.7 or later - (the only "python 2" code there is import Tkinter which becomes import tkinter in Python 3). Python 2 is really at the end of line, and there are no updates for projects like pygame on it..

That said, here is your code, modified to run on Linux + Python 3 (should still work on Windows), and to actually perform some actions using the embedded pygame frame.

import tkinter as tkimport osimport platformimport pygameimport timeclass window(object):    def __init__(self):        self.root = tk.Tk()  # Main window        self.root.title("SquareScape")        # self.root.iconbitmap(r'C:\Users\17_es\PycharmProjects\square_puzzle\images\icon.ico')        self.root.configure(background='#9b9b9b')        # Large Frame        self.win_frame = tk.Frame(self.root, width=670, height=520, highlightbackground='#595959', highlightthickness=2)        # menu (left side)        self.menu = tk.Frame(self.win_frame, width=150, height=516, highlightbackground='#595959', highlightthickness=2)        self.menu_label = tk.Label(self.menu, text="Settings", bg='#8a8a8a', font=("Courier", "16", "bold roman"))        self.mute = tk.Button(self.menu, text="XXXX", font="Courier", bg='#bcbcbc', activebackground='#cdcdcd')        tk.Button(self.menu, text="<->", command=lambda: setattr(self, "direction", (-self.direction[0], self.direction[1]))).pack()        tk.Button(self.menu, text="^", command=lambda: setattr(self, "direction", (self.direction[0], -self.direction[1]))).pack()        # pygame        self.pygame_frame = tk.Frame(self.win_frame, width=514, height=514, highlightbackground='#595959', highlightthickness=2)        self.embed = tk.Frame(self.pygame_frame, width=512, height=512,)        # Packing        self.win_frame.pack(expand=True)        self.win_frame.pack_propagate(0)        self.menu.pack(side="left")        self.menu.pack_propagate(0)        self.menu_label.pack(ipadx=60, ipady=2)        self.mute.pack(ipadx=40, ipady=2, pady=5)        self.pygame_frame.pack(side="left")        self.embed.pack()        #This embeds the pygame window        os.environ['SDL_WINDOWID'] = str(self.embed.winfo_id())        system = platform.system()        if system == "Windows":            os.environ['SDL_VIDEODRIVER'] = 'windib'        elif system == "Linux":            os.environ['SDL_VIDEODRIVER'] = 'x11'        self.root.update_idletasks()        #Start pygame        pygame.init()        self.win = pygame.display.set_mode((512, 512))        self.bg_color = (255, 255, 255)        self.win.fill(self.bg_color)        self.pos = 0, 0        self.direction = 10, 10        self.size = 40        self.color = (0, 255, 0)        self.root.after(30, self.update)        self.root.mainloop()    def update(self):        first_move = True        pygame.draw.rect(self.win, self.bg_color, self.pos + (self.size, self.size))        self.pos = self.pos[0] + self.direction[0], self.pos[1] + self.direction[1]        if self.pos[0] < 0 or self.pos[0] > 512 - self.size:            self.direction = -self.direction[0], self.direction[1]            self.pos = self.pos[0] + 2 * self.direction[0], self.pos[1] + self.direction[1]        if self.pos[1] < 0 or self.pos[1] > 512 - self.size:            self.direction = self.direction[0], -self.direction[1]            self.pos = self.pos[0] + self.direction[0], self.pos[1] + 2 * self.direction[1]        pygame.draw.rect(self.win, self.color, self.pos + (self.size, self.size))        pygame.display.flip()        self.root.after(30, self.update)screen = window()tk.mainloop()