如何使用 OOP 在 Tkinter 中调用特定屏幕

How to call a particular screen in Tkinter using OOP

我正在尝试通过将 Tkinter 代码放入 classes 来清理它,但我无法调用特定屏幕。当我只使用函数时,我到处都使用 Something.place_forget() 来获取下一页。我所有的小部件都是在全局范围内定义的,因此这是必要的,但是我希望能够从 class 中调用方法,在这些方法中我在各自的本地范围内定义了我的小部件。

tkinter imports[...]
from functools import partial

gui = Tk()
gui.geometry("700x700")
pagenumber = 1


class Input:

    def __init__(self, screen):
        self.screen = screen

    def checkPage(self, page):
        global pagenumber
        pagenumber = page
        print(pagenumber)

    def mainscreen(self):
        global pagenumber
        button_input = Button(self.screen, text="Input", padx="50", pady="25", bg="lightgrey",
                              command=partial(self.checkPage, 2))
        [...]
        button_input.place(x="400", y="350")

    def infoPage(self):
        title_enter = Label(self.screen, text="Enter")
            [...]
        submit.place(x="290", y="420")

    def ingredientsPage(self):
        pass


inputscreen = Input(gui)

if pagenumber == 1:
    inputscreen.mainscreen()
elif pagenumber == 2:
    print("reached")
    inputscreen.infoPage()

gui.mainloop()

我想做的是检查页码(在 class 中更新)并使用它来显示其各自的页面。尽管 pagenumber 更新正常,但它没有显示应有的屏幕。

看起来不错,您缺少一件事,即实际更新屏幕的回调。

def page_monitor():
    if pagenumber == 1:
        inputscreen.mainscreen()
    elif pagenumber == 2:
        print("reached")
        inputscreen.infoPage()
    gui.after(1000, page_monitor)

page_monitor()

我不确定这是否会像您希望的那样工作,您很可能仍然需要忘记不想显示的小部件。您可以轻松地在 class 中创建一个函数来忘记所有小部件的位置,并在 inputscreen.infoPage() 和 inputscreen.mainscreen() 方法中调用它们。在未放置的小部件上调用 place_forget() 并没有坏处,因此这是最简单的方法。我从来没有测试过性能。

tkinter imports[...]
from functools import partial

gui = Tk()
gui.geometry("700x700")
pagenumber = 1


class Input:
    def __init__(self, screen):
        self.screen = screen
        self.button_input = Button(self.screen, text="Input", padx="50", 
                                   pady="25", bg="lightgrey",
                                   command=partial(self.changePage, 2))
        self.title_enter = Label(self.screen, text="Enter")

    def changePage(self, page):
        global pagenumber
        pagenumber = page
        print(pagenumber)

    def forget_widgets()
        self.button_input.place_forget()
        self.title_enter.place_forget()

    def mainscreen(self):
        self.forget_widgets()
        self.button_input.place(x="400", y="350")

    def infoPage(self):
        self.forget_widgets()
        self.title_enter.place(x="290", y="420")


    def ingredientsPage(self):
        pass


inputscreen = Input(gui)

def page_monitor():
    if pagenumber == 1:
        inputscreen.mainscreen()
    elif pagenumber == 2:
        print("reached")
        inputscreen.infoPage()
    gui.after(1000, page_monitor)

page_monitor()
gui.mainloop()

如果您想要制作忘记最后一页变量的函数,您只需要将程序设计为仅可预测地从一页流到另一页,或者创建一个全局变量来跟踪您所在的最后一页并更新它每当您的页面更改时。我没有 运行 这段代码,所以如果有任何错误,我深表歉意。

这个答案是由 acw 给出的,但我把它放在这里是因为他没有直接在 Whosebug 上回答。基本上使用 clear 方法然后调用你的下一个 class.

from tkinter import *
from functools import partial

gui = Tk()
gui.geometry("700x700")

class Input:
    def __init__(self, screen):
        self.screen = screen

    def checkPage(self, page):
        if page == 1:
            self.clear()
            self.mainscreen()
        elif page == 2:
            self.clear()
            self.infoPage()

    def clear(self):
        for widget in self.screen.winfo_children():
            widget.destroy()

    def mainscreen(self):
        button_input = Button(self.screen, text="InfoPage", padx="50", pady="25", bg="lightgrey",
                              command=partial(self.checkPage, 2))
        button_input.place(x="400", y="350")

    def infoPage(self):
        title_enter = Label(self.screen, text="Enter")
        title_enter.place(x="290", y="420")

        button_input = Button(self.screen, text="MainScreen", padx="50", pady="25", bg="lightgrey",
                              command=partial(self.checkPage, 1))
        button_input.place(x="200", y="150")

    def ingredientsPage(self):
        pass


inputscreen = Input(gui)
inputscreen.checkPage(1)
gui.mainloop()