多个屏幕|Python Tkinter

qcuzuvrc  于 2023-10-21  发布在  Python
关注(0)|答案(1)|浏览(205)

我正在尝试创建一个具有多个屏幕的程序。我有它的工作,如果我点击主屏幕中的按钮,它确实切换屏幕,但一旦在屏幕上,我试图点击其他按钮回到主屏幕,它不工作。我该如何解决这个问题,让它回到主屏幕?

import tkinter as tk
from tkinter import ttk
from tkinter import font
from tkinter import messagebox

win = tk.Tk()
# Screen
screen = tk.Tk()
screen.title('Main Menu')
screen.geometry('600x400')

# Font
style1 = font.Font(size=25)
style2 = font.Font(size=20)

## Direction Screen || Text, Back Button (Returns to main Screen)
class how_to_play(tk.Toplevel):
    def __init__(self):
        super().__init__()
        win.title('How To Play')
        win.geometry('600x400')
        ttk.Label(self, text = 'Game Insturctions').pack()
        ttk.Label(self, text = 'another label').pack()
        ttk.Button(self, text = 'Exit', command = main_menu).pack()

# Game Screen || Hang Man, Letter/Word Input, Trys left, Incorrt Answers, Back Button (Returns to Main Screen)
def game():
    game = tk.Toplevel()
    game.title('Hang Man')
    game.geometry('600x400')
    ttk.Label(game, text = 'Hang Man').pack()
    ttk.Button(game, text = 'Exit', command = main_menu).pack()
    ttk.Label(game, text = 'another label').pack(expand = True)
    
# Main Menu Screen
def main_menu():
    menu = tk.Toplevel()
    menu.title('Main Menu')
    menu.geometry('600x400')
    ttk.Label(screen, text = 'Main Menu').pack()
    button1 = ttk.Button(screen, text = 'How To Play', command = how_to_play)
    button1.pack(expand = True)

    button2 = ttk.Button(screen, text = 'Play', command = game)
    button2.pack(expand = True)
    
# run 
main_menu()
screen.mainloop()

5lhxktic

5lhxktic1#

你对所有的Toplevel有点困惑。你真的想要单独的Windows吗?
如果是这样,那么按照与how_to_play相同的方式为game创建一个类。这样你就可以从主窗口(主菜单)的按钮示例化两者。简单地返回destroy()顶层,只保留主窗口:

多窗口解决方案:

import tkinter as tk
from tkinter import ttk

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Main Menu')
        self.geometry('600x400')
        ttk.Label(self, text='Main Menu').pack()
        button1 = ttk.Button(self, text='How To Play', command=self.InstrScreen)
        button1.pack(expand=True)
        button2 = ttk.Button(self, text='Play', command=self.GameScreen)
        button2.pack(expand=True)

    # Direction Screen as Toplevel
    class InstrScreen(tk.Toplevel):
        def __init__(self):
            super().__init__()
            self.title('How To Play')
            self.geometry('600x400')
            ttk.Label(self, text='Game Insturctions').pack()
            ttk.Label(self, text='another label').pack()
            ttk.Button(self, text='Exit', command=self.destroy).pack()

    # Game Screen as Toplevel
    class GameScreen(tk.Toplevel):
        def __init__(self):
            super().__init__()
            self.title('Hang Man')
            self.geometry('600x400')
            ttk.Label(self, text='Hang Man').pack()
            ttk.Button(self, text='Exit', command=self.destroy).pack()
            ttk.Label(self, text='another label').pack(expand=True)

if __name__ == '__main__':
    # instanciate App and run it
    app = App()
    app.mainloop()

单一窗口解决方案:

但如果你实际上只想改变内容,而不想打开多个窗口,你必须创建单独的框架和pack()pack_forget(),这取决于你想要显示的内容:

import tkinter as tk
from tkinter import ttk
from functools import partial

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Main Menu')
        self.geometry('600x400')
        # initialize main menu as frame
        self.main_menu_frame = tk.Frame(self)
        ttk.Label(self.main_menu_frame, text='Main Menu').pack()
        button1 = ttk.Button(self.main_menu_frame, text='How To Play', command=self.show_how_to_play)
        button1.pack(expand=True)
        button2 = ttk.Button(self.main_menu_frame, text='Play', command=self.init_game)
        button2.pack(expand=True)
        # Direction Screen as frame
        self.instructions_frame = tk.Frame(self)
        ttk.Label(self.instructions_frame, text='Game Insturctions').pack()
        ttk.Label(self.instructions_frame, text='another label').pack()
        ttk.Button(self.instructions_frame, text='Exit',
                   command=partial(self.back_to_main_menu, self.instructions_frame)).pack()
        # Game Screen as frame
        self.game_frame = tk.Frame(self)
        ttk.Label(self.game_frame, text='Hang Man').pack()
        ttk.Button(self.game_frame, text='Exit', command=partial(self.back_to_main_menu, self.game_frame)).pack()
        ttk.Label(self.game_frame, text='another label').pack(expand=True)
        # only pack menu to start with
        self.main_menu_frame.pack()

    # function to unload the menu frame, change the window title and load instructions frame
    def show_how_to_play(self):
        self.main_menu_frame.pack_forget()
        self.title('How To Play')
        self.instructions_frame.pack()

    # function to unload the menu frame, change the window title and load game frame
    def init_game(self):
        self.main_menu_frame.pack_forget()
        self.title('Hang Man')
        self.game_frame.pack()

    # function to unload either the instructions or game frame, change the window title and load menu frame
    # since it is triggeret by both the button in game and instructions frame the button has to pass the frame to unload
    def back_to_main_menu(self, from_where):
        from_where.pack_forget()
        self.title('Main Menu')
        self.main_menu_frame.pack()

if __name__ == '__main__':
    # instanciate App and run it
    app = App()
    app.mainloop()

相关问题