【问题标题】:Embedding a Pygame window into a Tkinter or WxPython frame将 Pygame 窗口嵌入到 Tkinter 或 WxPython 框架中
【发布时间】:2014-06-12 16:46:49
【问题描述】:

我和一个朋友正在 pygame 中制作游戏。我们希望将 pygame 窗口嵌入到 tkinter 或 WxPython 框架中,以便我们可以包含 WX 或 Tkinter 支持的文本输入、按钮和下拉菜单。我已经在互联网上搜索了答案,但我发现的只是人们问同样的问题,这些都没有得到很好的回答。

实现嵌入 tkinter 或 WX 框架的 pygame 显示的最佳方法是什么? (TKinter 更好)

这些功能可以与 pygame 显示一起包含的任何其他方式也可以工作。

【问题讨论】:

    标签: python tkinter wxpython pygame embed


    【解决方案1】:

    (请注意,此解决方案不适用于装有 Pygame 2 的 Windows 系统。 见Using 'SDL_WINDOWID' does not embed pygame display correctly into another application #1574。您目前可以下载旧版本的 Pygame here。)

    根据this SO question 和接受的答案,最简单的方法是使用 SDL 绘图框。

    此代码是 SO 用户 Alex Sallons 的工作。

    import os
    import pygame
    import Tkinter as tk
    from Tkinter import *
    
    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()
    

    此代码是跨平台的,只要在非 Windows 系统上省略 windib SDL_VIDEODRIVER 行。我会建议

    # [...]
    import platform
    if platform.system == "Windows":
        os.environ['SDL_VIDEODRIVER'] = 'windib'
    # [...]
    

    【讨论】:

    • 尝试用root.after(0,pygame.display.update)替换最后的循环。
    • 然后我会使用 root.mainloop() 吗?我可能在主循环中需要做一些其他的事情,但我也可以在它们上使用 root.after。我会试试这个,虽然我不确定 root.update 会如何导致错误......
    • 不,应该替换它。您可以创建一个调用pygame.display.update 的函数并将其传递给root.after。我也不清楚root.update 是如何导致错误的。好奇怪……
    • 我知道这将调用更新(以及我可能想要调用的任何其他函数)但是,这真的会更新 root 并调用这些东西吗?我承认在 wx 中设置像这样的计时器有更多经验,但是在 wx 中你设置计时器并启动 root.mainloop()。不过,我会尝试几种方法。奇怪的是 root.update() 会导致问题,但是其他一两个页面暗示了这一点。
    • 看来 root.after 会为这个函数安排一个定时器。但是,这不会真正取代 root.update,除非有办法让它反复重置计时器并定期运行,使其能够使用 root.mainloop()
    【解决方案2】:

    这里有一些链接。

    基本上有很多方法。

    • 在 Linux 上,您可以轻松地embed 任何应用程序在一个框架内另一个框架内。很简单。
    • 将 Pygame 输出直接输出到 WkPython 画布

    一些研究会提供相关代码。

    【讨论】:

    • 如果您想知道的话,我已经查看了所有这些内容。然而,没有人回答这个简单的问题,即如何制作一个非常基本的窗口,其中包含一个带有 pygame 的框架。
    • 我假设您使用 Windows,因为您没有说。 WxPython 页面上的代码示例(适用于 Windows)是否有效?如果没有,会发生什么?
    • 仅供参考:提供赏金的人不会奖励任何人,除非答案真的很好。
    • 是的,我猜到了。事实上,我认为为一个可悲的答案获得很多代表是错误的。然而,这是,唯一的答案是自动取款机。无论如何,我正在努力提供帮助。
    • 另外,AFAIK,某人或其他人已经找到了this,这几乎可以满足您的需求。
    【解决方案3】:

    根据回溯,程序因 TclErrors 而崩溃。这些是由于试图同时在两个不同的线程中访问相同的文件、套接字或类似资源而引起的。在这种情况下,我认为这是线程内屏幕资源的冲突。然而,这实际上并不是由于两个旨在自主运行的 gui 程序出现的内部问题。这些错误是由于主线程已接管而不需要调用 root.update() 的单独线程的产物。仅当主线程不这样做时,才通过使线程调用 root.update() 来停止这种情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多