簡體   English   中英

將 Python 中的標准輸出重定向到 PyGame

[英]Redirecting stdout in Python into PyGame

我這里有一個非常奇怪的用例,我正在嘗試為我的學生編寫一些簡單的程序來幫助他們學習 python。為了讓它工作,我有一個 PyGame window 嵌入在一個 TKinter 框架中,我需要重定向 stdout 以更改 PyGame window 中的某些內容。我有重定向工作,如果我將它重定向到一個文件它工作正常,但如果我嘗試更改文本它不起作用。 我將一個字符串硬編碼到 PyGame 文本更改代碼中並且可以正常工作,但由於某些原因它不適用於重定向的文本。

重定向 class:

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:

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('Hello Friend,')。它會將其重定向為 PyGame 框中某人的對話框,從長遠來看可能無法正常工作,但我必須克服這一點才能真正弄清楚)

編輯:

所以問題是,當我單擊按鈕時,出於某種原因,write function 被調用了兩次,它在輸入的字符串上調用 print,然后在空字符串上再次調用。 仍然不確定如何解決它,但至少我找到了問題

好的,所以我發現了問題。

看起來 print 向 stdout 發送了兩件事,即要打印的字符串和結束字符。 所以它覆蓋了我想要用換行符打印的字符串。 我改變了我的 PrintTest class 來適應這個:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM