简体   繁体   English

将 Pygame 窗口嵌入到 Tkinter 或 WxPython 框架中

[英]Embedding a Pygame window into a Tkinter or WxPython frame

A friend and I are making a game in pygame.我和一个朋友正在 pygame 中制作游戏。 We would like to have a pygame window embedded into a tkinter or WxPython frame, so that we can include text input, buttons, and dropdown menus that are supported by WX or Tkinter.我们希望将 pygame 窗口嵌入到 tkinter 或 WxPython 框架中,以便我们可以包含 WX 或 Tkinter 支持的文本输入、按钮和下拉菜单。 I have scoured the internet for an answer, but all I have found are people asking the same question, none of these have been well answered.我已经在互联网上搜索了答案,但我发现的只是人们问同样的问题,这些都没有得到很好的回答。

What would be the best way implement a pygame display embedded into a tkinter or WX frame?实现嵌入到 tkinter 或 WX 框架中的 pygame 显示的最佳方法是什么? (TKinter is preferable) (TKinter 更可取)

Any other way in which these features can be included alongside a pygame display would also work.可以将这些功能与 pygame 显示一起包含的任何其他方式也可以使用。

(Note this solution does not work on Windows systems with Pygame 2. See Using 'SDL_WINDOWID' does not embed pygame display correctly into another application #1574 . You can currently download older versions of Pygame here .) (请注意,此解决方案不适用于带有 Pygame 2 的 Windows 系统。请参阅使用“SDL_WINDOWID”不会将 pygame 显示正确嵌入另一个应用程序 #1574 。您目前可以在此处下载旧版本的 Pygame。)

According to this SO question and the accepted answer, the simplest way to do this would be to use an SDL drawing frame.根据这个SO question 和接受的答案,最简单的方法是使用 SDL 并条框。

This code is the work of SO user Alex Sallons .此代码是 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()

This code is cross-platform, as long as the windib SDL_VIDEODRIVER line is omitted on non Windows systems.此代码是跨平台的,只要在非 Windows 系统上省略了windib SDL_VIDEODRIVER 行。 I would suggest我会建议

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

Here are some links.这里有一些链接。

Basically, there are many approaches.基本上,有很多方法。

  • On Linux, you can easily embed any application in a frame inside another.在 Linux 上,您可以轻松地将任何应用程序embed到另一个框架中。 Simple.简单的。
  • Direct Pygame output to a WkPython Canvas将 Pygame 直接输出到 WkPython 画布

Some research will provide the relevant code.一些研究将提供相关代码。

According to the tracebacks, the program crashes due to TclErrors.根据回溯,程序由于 TclErrors 而崩溃。 These are caused by attempting to access the same file, socket, or similar resource in two different threads at the same time.这些是由于试图同时在两个不同的线程中访问相同的文件、套接字或类似资源而引起的。 In this case, I believe it is a conflict of screen resources within threads.在这种情况下,我认为这是线程内屏幕资源的冲突。 However, this is not, in fact, due to an internal issue that arises with two gui programs that are meant to function autonomously.然而,这实际上并不是由于两个旨在自主运行的 gui 程序出现的内部问题。 The errors are a product of a separate thread calling root.update() when it doesn't need to because the main thread has taken over.这些错误是由于主线程已接管而不需要调用 root.update() 的单独线程的产物。 This is stopped simply by making the thread call root.update() only when the main thread is not doing so.仅当主线程不这样做时,才通过使线程调用 root.update() 来停止这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM