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 becomesimport 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()