Examples for this were difficult to find, so hopefully this answer will help others. In working with the pySDL2 wrapper API, you need to know about ctypes for different operations. In some cases, the API has been extended to avoid some of these seemingly arcane actions. An example code is provided and then explained below.
from sdl2 import *
import tkinter as tk
from tkinter import *
import random, ctypes
def draw():
global renderer
x1 = ctypes.c_int(random.randrange(0, 600))
y1 = ctypes.c_int(random.randrange(0, 500))
x2 = ctypes.c_int(random.randrange(0, 600))
y2 = ctypes.c_int(random.randrange(0, 500))
r = ctypes.c_ubyte(random.randrange(0, 255))
g = ctypes.c_ubyte(random.randrange(0, 255))
b = ctypes.c_ubyte(random.randrange(0, 255))
SDL_SetRenderDrawColor(renderer, r, g, b, ctypes.c_ubyte(255))
SDL_RenderDrawLine(renderer, x1, y1, x2, y2)
def sdl_update():
global window, event, renderer
SDL_RenderPresent(renderer);
if SDL_PollEvent(ctypes.byref(event)) != 0:
if event.type == SDL_QUIT:
SDL_DestroyRenderer(renderer)
SDL_DestroyWindow(window)
SDL_Quit()
# tkinter stuff #
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)
button1 = Button(buttonwin,text = 'Draw', command=draw)
button1.pack(side=LEFT)
root.update()
#################################
# SDL window stuff #
SDL_Init(SDL_INIT_VIDEO)
window = SDL_CreateWindowFrom(embed.winfo_id())
renderer = SDL_CreateRenderer(window, -1, 0)
SDL_SetRenderDrawColor(renderer, ctypes.c_ubyte(255), ctypes.c_ubyte(255),
ctypes.c_ubyte(255), ctypes.c_ubyte(255))
SDL_RenderClear(renderer)
event = SDL_Event()
draw()
while True:
sdl_update()
root.update()
The example above shows that you can create your tkinter GUI, and then initialize your pySDL2 code, creating a window from whichever frame or window you want, in this case, I've chosen to use a frame I've created, called embed
. Using the winfo_id()
function available (see the tkinter docs) we can get a handle to the window. The draw()
function simply does the drawing using the render module. Notice that for the SDL2 functions that expect certain types, ctypes
is used to format those parameters in a way that is expected by SDL2. In the main while loop, a call to the sdl_update()
function checks for SDL events. That is followed by the root window (tkinter) update call.
The Button
we created has its command linked to draw()
and when you click this button, a randomly colored line appears in the frame the SDL2 window is linked to.
This code was adapted from This SO answer from PythonNut regarding pygame and tkinter. That code was originally by user Alex Sallons.