gpt4 book ai didi

python - 我正在将 pygame 窗口嵌入到 Tkinter 中,如何操作 pygame 窗口?

转载 作者:行者123 更新时间:2023-12-01 08:00:32 27 4
gpt4 key购买 nike

所以我正在 pygame 中制作游戏,并且我也想使用 tkinter。我将 pygame 窗口嵌入到 tkinter 窗口中,但我似乎无法用它做任何事情。

对于上下文,这里是完整的代码:

import Tkinter as tk
import os
import platform
import pygame

class window(object):
def __init__(self):
self.root = tk.Tk() # Main window
self.root.title("SquareScape")
self.root.iconbitmap(r'C:\Users\17_es\PycharmProjects\square_puzzle\images\icon.ico')
self.root.configure(background='#9b9b9b')

# Large Frame
self.win_frame = tk.Frame(self.root, width=670, height=520, highlightbackground='#595959', highlightthickness=2)

# menu (left side)
self.menu = tk.Frame(self.win_frame, width=150, height=516, highlightbackground='#595959', highlightthickness=2)
self.menu_label = tk.Label(self.menu, text="Settings", bg='#8a8a8a', font=("Courier", "16", "bold roman"))
self.mute = tk.Button(self.menu, text="XXXX", font="Courier", bg='#bcbcbc', activebackground='#cdcdcd')

# pygame
self.pygame_frame = tk.Frame(self.win_frame, width=514, height=514, highlightbackground='#595959', highlightthickness=2)
self.embed = tk.Frame(self.pygame_frame, width=512, height=512,)

# Packing
self.win_frame.pack(expand=True)
self.win_frame.pack_propagate(0)

self.menu.pack(side="left")
self.menu.pack_propagate(0)
self.menu_label.pack(ipadx=60, ipady=2)
self.mute.pack(ipadx=40, ipady=2, pady=5)

self.pygame_frame.pack(side="left")
self.embed.pack()

#This embeds the pygame window
os.environ['SDL_WINDOWID'] = str(self.embed.winfo_id())
if platform.system == "Windows":
os.environ['SDL_VIDEODRIVER'] = 'windib'

#Start pygame
pygame.init()
self.win = pygame.display.set_mode((512, 512))
self.win.fill(pygame.Color(255, 255, 255))
pygame.display.init()

self.root.mainloop()

screen = window()

#Here is sample code that I want to run
pygame.draw.rect(screen.win, (0, 0, 255), (200, 200, 100, 100))

当我使用pygame.draw.rect(screen.win, (0, 0, 255), (200, 200, 100, 100))时, 什么都没发生。在类中使用 pygame 是有效的,但在我更复杂的游戏中,对所有变量使用 self.variable 似乎没有必要。

如何在窗口类之外的 pygame 窗口中运行我的代码?

最佳答案

所以 - 除了明显缺少对 pygame.display.flip 的调用之外 - 我想这就是您调用 pygame.display.init 的目的(pygame.init 已经调用了这个) - 我发现 tkinter 需要在打包的框架完全可供 Pygame 使用之前初始化其窗口和小部件。

我通过在调用 pygame.init 之前添加对 self.root.update_idletasks() 的调用来实现这一点,并为我的平台显式设置视频驱动程序(您已经在 Windows 中这样做了),使事情正常进行。

无论如何,在您的代码中,您没有显示您是否想要调用 Pygamedrawing 函数 - 事实上,很可能一切都是正确的,但是 screen.window() 之后的代码 只是永远不会运行(或者更确切地说,只是在程序退出时运行) - 因为您在应用程序类的 __init__ 方法内调用 tkinter.mainloop。

将对 mainloop 的调用移至 __init__ 之外是一个很好的做法,因此您也可以初始化其他对象和资源 - 并且您实际上确实拥有 screen 对象来进行操作。通过在 __init__ 内部进行调用,就像整个程序在“初始化内部”运行一样。

简而言之:

  • 在初始化 pygame 之前调用 tkinter.update_iddletasks()
  • 记住在使用 Pygame 绘制任何内容后调用 pygame.display.flip
  • 安排您的代码,以便您的绘图调用真正执行,并且在调用进入 tkinter 循环后不会被阻塞
  • 您应该认真考虑使用Python 3.7或更高版本 - (唯一的“python 2”代码是import Tkinter,它变成import tkinter在Python 3)。 Python 2 确实已经到了最后阶段,并且没有像 pygame 这样的项目的更新。.
也就是说,这是您的代码,修改为在 Linux + Python 3 上运行(应该仍然可以在 Windows 上运行),并使用嵌入式 pygame 框架实际执行一些操作。

import tkinter as tk
import os
import platform
import pygame
import time

class window(object):
def __init__(self):
self.root = tk.Tk() # Main window
self.root.title("SquareScape")
# self.root.iconbitmap(r'C:\Users\17_es\PycharmProjects\square_puzzle\images\icon.ico')
self.root.configure(background='#9b9b9b')

# Large Frame
self.win_frame = tk.Frame(self.root, width=670, height=520, highlightbackground='#595959', highlightthickness=2)

# menu (left side)
self.menu = tk.Frame(self.win_frame, width=150, height=516, highlightbackground='#595959', highlightthickness=2)
self.menu_label = tk.Label(self.menu, text="Settings", bg='#8a8a8a', font=("Courier", "16", "bold roman"))
self.mute = tk.Button(self.menu, text="XXXX", font="Courier", bg='#bcbcbc', activebackground='#cdcdcd')

tk.Button(self.menu, text="<->", command=lambda: setattr(self, "direction", (-self.direction[0], self.direction[1]))).pack()
tk.Button(self.menu, text="^", command=lambda: setattr(self, "direction", (self.direction[0], -self.direction[1]))).pack()

# pygame
self.pygame_frame = tk.Frame(self.win_frame, width=514, height=514, highlightbackground='#595959', highlightthickness=2)
self.embed = tk.Frame(self.pygame_frame, width=512, height=512,)

# Packing
self.win_frame.pack(expand=True)
self.win_frame.pack_propagate(0)

self.menu.pack(side="left")
self.menu.pack_propagate(0)
self.menu_label.pack(ipadx=60, ipady=2)
self.mute.pack(ipadx=40, ipady=2, pady=5)

self.pygame_frame.pack(side="left")
self.embed.pack()
#This embeds the pygame window
os.environ['SDL_WINDOWID'] = str(self.embed.winfo_id())
system = platform.system()
if system == "Windows":
os.environ['SDL_VIDEODRIVER'] = 'windib'
elif system == "Linux":
os.environ['SDL_VIDEODRIVER'] = 'x11'

self.root.update_idletasks()
#Start pygame
pygame.init()
self.win = pygame.display.set_mode((512, 512))

self.bg_color = (255, 255, 255)
self.win.fill(self.bg_color)
self.pos = 0, 0
self.direction = 10, 10
self.size = 40
self.color = (0, 255, 0)
self.root.after(30, self.update)

self.root.mainloop()


def update(self):

first_move = True
pygame.draw.rect(self.win, self.bg_color, self.pos + (self.size, self.size))


self.pos = self.pos[0] + self.direction[0], self.pos[1] + self.direction[1]


if self.pos[0] < 0 or self.pos[0] > 512 - self.size:
self.direction = -self.direction[0], self.direction[1]
self.pos = self.pos[0] + 2 * self.direction[0], self.pos[1] + self.direction[1]
if self.pos[1] < 0 or self.pos[1] > 512 - self.size:
self.direction = self.direction[0], -self.direction[1]
self.pos = self.pos[0] + self.direction[0], self.pos[1] + 2 * self.direction[1]

pygame.draw.rect(self.win, self.color, self.pos + (self.size, self.size))
pygame.display.flip()
self.root.after(30, self.update)


screen = window()
tk.mainloop()

关于python - 我正在将 pygame 窗口嵌入到 Tkinter 中,如何操作 pygame 窗口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55755305/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com