简体   繁体   中英

Tkinter window and pygame window open at same time

I am trying to create a program that has a tkinter window open, and then when you push a button, it closes the tkinter window and opens a pygame window. However, when I click the button to open the pygame window, it opens the pygame window and the tkinter window stays open.

Code:

import tkinter as tk
import pygame

root = tk.Tk()
btn = tk.Label(root, text="Start")
btn.bind("<Button-1>", lambda x: root.quit())
btn.pack()

root.mainloop()
root.destroy()

win = pygame.display.set_mode((500, 500))
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    win.fill((255, 255, 255))
    pygame.display.update()
pygame.quit()

I have also tried using:

btn.bind("<Button-1>", lambda x: root.destroy())
btn.bind("<Button-1>", root.quit)
btn.bind("<Button-1>", root.destroy)
btn.bind("<Button-1>", lambda: root.quit())
btn.bind("<Button-1>", lambda: root.destroy())
def start(event=None):
    root.quit()
btn.bind("<Button-1>", start)

How can I fix this? (I'm running Python 3.7.7 on MacOS 11.1)

I cannot reproduce the issue. However I recommend to use the tkinter window to a function or class. Call destroy when the key is pressed rather than after the main loop exits. Invoking the destroy command will cause and error if the application has already been destroyed, for example if the window is closed manually.

import tkinter as tk
import pygame

def runTk():
    root = tk.Tk()
    btn = tk.Label(root, text="Start")
    btn.bind("<Button-1>", lambda x: root.destroy())
    btn.pack()
    root.mainloop()

runTk()

win = pygame.display.set_mode((500, 500))
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    win.fill((255, 255, 255))
    pygame.display.update()
pygame.quit()

I tried organising your code in a class, so it is a bit easier to make modifications to it and calling the individual components.

Aside of that, I changed your btn to use tk.Button instead of tk.Label (thought it made more sense in the context)

The actual toggle function calls the self.tk_root.withdraw() command. This effectively hides the root tk window - you can make it appear again by calling self.tk_root.deiconify() . If you also wish to destroy the root after you have hidden it, you can simply add a self.tk_root.destroy() after the withdraw.

Edit: If withdraw() isn't working for you, try to use iconify() instead.

import tkinter as tk
import pygame


class TkPygame:
    def __init__(self):
        self.tk_root = tk.Tk()

        self.make_tk_widgets()

        self.tk_root.mainloop()

    def make_tk_widgets(self):
        btn = tk.Button(self.tk_root, text='Start', command=self.toggle_to_pygame)
        btn.pack()

    def toggle_to_pygame(self):
        self.tk_root.withdraw()
        self.make_pygame_window()

    def make_pygame_window(self):
        pygame_root = pygame.display.set_mode((500, 500))
        run = True
        while run:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    run = False
            pygame_root.fill((255, 255, 255))
            pygame.display.update()
        pygame.quit()


TkPygame()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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