5

using bits of code from another question, I embedded a pygame window in a tkinter window, I'm trying to make a tkbutton that draws a circle on the pygame window, been experimenting for a while and haven't turned any results so far. Any ideas would be great! Here's the code I have so far...

import Tkinter as tk
import os
import pygame as py

#         R   G  B
red =   (225, 0, 0)
green = (0, 255, 0)
w, h = 500, 200

p = False

def maketrue(p):
    p = True
    returnp

root = tk.Tk()
window = tk.Frame(root, width=w, height=h)
window.pack()

os.environ['SDL_WINDOWID'] = str(window.winfo_id())

root.update

py.display.init()
screen = py.display.set_mode((w, h))
screen.fill(py.Color(255, 0, 0))
drawbutton = tk.Button(root, text='Draw Circle', command = maketrue(p))
drawbutton.pack()

while True:
    if p == True:
        py.draw.circle(screen, red, (250, 50), 20)
        py.display.update()
    else:
        pass
    py.draw.circle(screen, green, (250, 100), 20)

    root.update()
nbro
  • 15,395
  • 32
  • 113
  • 196
Alex Sallons
  • 159
  • 3
  • 9
  • 2
    I don't know anything about pygame so I can't help, but I do know that you need to call `root.mainloop` for Tkinter to work properly. Also, if you're using Tkinter you should avoid having your own infinite loop, since `mainloop` already serves that purpose. – Bryan Oakley Nov 24 '12 at 22:25
  • What part is and isn't working, after trying Bryan's comment? – ninMonkey Nov 25 '12 at 06:59
  • It appears to be the button widget and it not wanting to carry out the draw function. Not entirely sure... – Alex Sallons Nov 26 '12 at 08:54
  • Don't worry I got it to work, the button was calling the function improperly, I'll upload code later – Alex Sallons Nov 26 '12 at 13:10
  • @Bryan Oakley already gave you the answer to your problem! You need to give TKinter control of your main loop. Then you could implement the loop you need for pygame either along the Tkinter OR launch another thread for it and terminate it when Tkinter's mainloop is exited. – Josep Valls Feb 28 '13 at 19:11

1 Answers1

8

Been meaning to do this for a while, but I had time now, this is some basic code, the program makes a tkinter window and then embeds a pygame window in a frame, it then makes another frame and puts a button on that window that when pressed, calls a function that tells pygame to draw a circle on the pygame window.

import pygame
import Tkinter as tk
from Tkinter import *
import os


root = tk.Tk()

embed = tk.Frame(root, width = 500, height = 500) #creates embed frame for pygame window
embed.grid(columnspan = (600), rowspan = 500) # Adds grid
embed.pack(side = LEFT) #packs window to the left

buttonwin = tk.Frame(root, width = 75, height = 500)
buttonwin.pack(side = LEFT)

os.environ['SDL_WINDOWID'] = str(embed.winfo_id())
os.environ['SDL_VIDEODRIVER'] = 'windib'

screen = pygame.display.set_mode((500,500))
screen.fill(pygame.Color(255,255,255))

pygame.display.init()
pygame.display.update()


def draw():
    pygame.draw.circle(screen, (0,0,0), (250,250), 125)
    pygame.display.update()


button1 = Button(buttonwin,text = 'Draw',  command=draw)
button1.pack(side=LEFT)

root.update()

while True:
    pygame.display.update()
    root.update()
Right leg
  • 16,080
  • 7
  • 48
  • 81
Alex Sallons
  • 159
  • 3
  • 9
  • 1
    A better way to do this is to call `pygame.display.update()` via `root.after`. That way you don't have to have your own mini event loop, and so you don't have to call `root.update`. – Bryan Oakley May 14 '13 at 23:00
  • Would this program work on an operating system other than windows? The "windib" os environ change looks like it might only work on windows, and I am considering embedding a pygame program in tkinter for multiple platforms. (I can only test this program on windows at the moment) – trevorKirkby May 03 '14 at 22:59
  • Never mind, while this is windows specific, according to http://stackoverflow.com/questions/8584272/using-pygame-features-in-tkinter it looks like this line can simply be omitted and the program works fine on other platforms. – trevorKirkby May 03 '14 at 23:12
  • Are there any potential errors that might occur when the the pygame display is a fully functioning game display embedded in the tkinter window? Because this code has raised some strange errors for me. It works perfectly for a time, then crashes for various reasons. – trevorKirkby May 06 '14 at 03:03
  • Not sure, it really hates running with the debugger on, is that why? – Alex Sallons May 16 '14 at 02:02
  • 3
    On Linux, I found I had to call `root.update()` before setting `SDL_WINDOWID`, otherwise I received an X server error (`BadWindow (invalid Window parameter)`) – boxama Dec 24 '17 at 14:50
  • There is quite a bit wrong with this code. I am not sure why it was upvoted so much. Importing tkinter twice. Using grid and pack on the same frame. Columnspan of 600??? that makes no sense and actually does nothing in the code here. Uses a while loop instead of the mainloop() and after() to manage updates and lots of PEP8 cleanup needed. Also does not handle window close well as it throws an error. – Mike - SMT Oct 15 '19 at 17:00