将Python中的stdout重定向到PyGame



我这里有一个非常奇怪的用例,我正试图为我的学生编写一些简单的程序,帮助他们学习python。为了让它工作起来,我在TKinter帧中嵌入了一个PyGame窗口,我需要重定向stdout来更改PyGame窗中的内容。我有重定向功能,如果我将其重定向到一个文件,它可以正常工作,但如果我试图更改文本,它就不起作用。我在PyGame文本更改代码中硬编码了一个字符串,这很有效,但由于某种原因,它无法处理重定向的文本。

重定向类:

class PrintTest:
def __init__(self, file, game):
self.f = file
self.game = game

def write(self, t):
f.write(t)
self.game.text = game.font.render(t, True, self.game.text_colors[1], self.game.text_colors[2])
self.game.textRect = self.game.text.get_rect()
self.game.textRect.center = (300, 300)
def flush(self):
pass

游戏类别:

class Game:
def __init__(self, root):
self.root = root
embed = tk.Frame(root, width=600, height=600)
embed.pack(side=tk.LEFT)
os.environ['SDL_WINDOWID'] = str(embed.winfo_id())
if platform.system == "Windows":
os.environ['SDL_VIDEODRIVER'] = 'windib'
self.text_colors = [(255,255,255),
(0,255,0),
(0,0,128)]
# initialize a pygame display
pygame.init()
self.screen = pygame.display.set_mode((600, 600))
self.screen.fill(pygame.Color('red'))
self.clock = pygame.time.Clock()
self.font = pygame.font.Font('freesansbold.ttf', 32)
self.text = self.font.render('Hello, world!', True, self.text_colors[1], self.text_colors[2])
self.textRect = self.text.get_rect()
self.textRect.center = (300, 300)
# TK Creation
helv = font.Font(family='Helvetica', size=18, weight='bold')
self.button = tk.Button(root, 
text="Change text",
font=helv,
command=self.change_text).pack()
self.user_input = tk.StringVar()
self.textbox = ttk.Entry(root, width=15, textvariable=self.user_input)
self.textbox.pack()
# ---------------------------------------------------------------
def change_text(self):
print(self.user_input.get())
def run(self):
# Pygame loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
self.screen.fill(pygame.Color('red'))    
self.screen.blit(self.text, self.textRect)
pygame.display.update()
try:
self.root.update()
except tk.TclError:
running = False   
pygame.quit()

我把标准输出设置成这样:

try:
root = tk.Tk()
root.geometry('1000x600')
game = Game(root)
f = open('text.txt', 'w')
sl = PrintTest(f, game)
sys.stdout = sl
game.run()
except Exception:
traceback.print_exc()
pygame.quit()

当我按原样运行时,如果我在框中键入hello,hello会打印到文件中,但一个null字符会放入pygame框中。我真的不太了解PyGame,不知道这是一个问题还是重定向问题。如有任何帮助,我们将不胜感激!

(如果你想知道这里的用例是什么,我会让他们"完成"一些程序,以便在PyGame中发生一些事情。因此,如果他们在给定字段中键入print("你好,朋友!"(,它会将其重定向为PyGame框中某个人的对话框。(。从长远来看,这可能不起作用,但我必须克服这一点才能真正弄清楚(

编辑:

所以问题是,当我单击按钮时,由于某种原因,write函数被调用了两次,它在键入的字符串上调用print,然后在空字符串上再次调用。仍然不确定如何修复它,但至少我发现了的问题

好的,所以我发现了问题。

看起来print向stdout发送了两个东西,即要打印的字符串和结束字符。所以它覆盖了我想要用换行符打印的字符串。我更改了PrintTest类以适应以下情况:

class PrintTest:
def __init__(self, file, game):
self.f = file
self.game = game
def write(self, t):
if t != 'n':
self.f.write(t)
self.game.text, self.game.textRect = game.font.render(t, self.game.text_colors[2])
self.game.textRect.center = (300, 300)
def flush(self):
pass

最新更新