如何在Tkinter GUI应用程序中嵌入SDL2窗口?

2024-05-19 07:58:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图通过pySDL2将SDL2窗口嵌入到我的Tkinter应用程序中。如何设置pySDL2窗口和渲染器,使渲染或绘图显示在嵌入的框架内?在

其他的例子展示了pygame,但是我发现我的pygame版本目前不能正确地使用SDL2。我知道pygame的其他实现也在尝试实现SDL2,但与SDL2的兼容性对我来说至关重要。在

正确工作的一个例子是Tkinter窗口中的一个框架,该窗口具有一个屏幕,当单击按钮时,通过pysdl2api将某些内容绘制到框架中。 在尝试使用其他地方的pygame解决方案时,我收到了一些不同的错误,包括BadWindow、BadDrawable(与X服务器函数有关)


Tags: 版本框架应用程序绘图内容屏幕tkinter地方
1条回答
网友
1楼 · 发布于 2024-05-19 07:58:18

这方面的例子很难找到,所以希望这个答案能对其他人有所帮助。你需要知道如何在不同的包装器中使用不同的包装器。在某些情况下,API已经过扩展,以避免某些看似神秘的操作。下面提供了一个示例代码,并对其进行了解释。在

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

上面的例子显示,您可以创建tkinter GUI,然后初始化pySDL2代码,从您想要的任何一个框架或窗口创建一个窗口,在本例中,我选择使用我创建的框架,称为embed。使用可用的winfo_id()函数(请参阅tkinter文档),我们可以获得窗口的句柄。draw()函数只是使用render模块进行绘图。请注意,对于期望某些类型的SDL2函数,ctypes被用来以SDL2期望的方式格式化这些参数。在主while循环中,调用sdl_update()函数将检查SDL事件。然后是根窗口(tkinter)更新调用。 我们创建的Button的命令链接到draw(),当您单击此按钮时,SDL2窗口链接的框架中将出现一条随机彩色的线。 此代码改编自This SO answer from PythonNut regarding pygame and tkinter。该代码最初由用户Alex Sallons编写。在

相关问题 更多 >

    热门问题