Python tkinter:如何确保每次单击按钮时只创建一个子窗口而不是新窗口?

sw1*_*456 2 python tkinter

目前正在学习 tkinter 并且已经走到了尽头。每次我单击 GUI 中的一个按钮(在登录屏幕中输入“用户名”和“密码”后)都会创建并出现一个新的子窗口。正如它应该。我现在想要做的是确保只创建一个窗口,并且任何后续的点击都不会创建更多的窗口。这怎么可能?

from tkinter import *

class Main():

    def __init__(self, master):
        self.master = master
        self.master.title("Main Window")

        self.button1 = Button(self.master, text="Click Me 1", command = self.Open1)
        self.button1.grid(row=0, column=0, sticky=W)
        self.button2 = Button(self.master, text="Click Me 2", command = self.Open2)
        self.button2.grid(row=0, column=2, sticky=W)
        self.button3 = Button(self.master, text="Close", command = self.Close)
        self.button3.grid(row=1, column=0, sticky=W)

    def Login(self):

        login_win = Toplevel(self.master)
        login_window = Login(login_win)
        login_window.Focus()
        #main_window.Hide()


    def Open1(self):
        second_window = Toplevel(self.master)
        window2 = Second(second_window)

    def Open2(self):
        third_window = Toplevel(self.master)
        window3 = Third(third_window)

    def Close(self):
        self.master.destroy()

    #def Hide(self):
        #self.master.withdraw()

    #def Appear(self):
        #self.master.deiconify()


class Second():

    def __init__(self, master):
        self.master = master
        self.master.title("Child 1 of Main")
        self.master.geometry("300x300")
        self.button4 = Button(self.master, text="Click Me 1", command = self.Open_Child)
        self.button4.grid(row=0, column=0, sticky=W)


    def Open_Child(self):
        second_child_window = Toplevel(self.master)
        window4 = Second_Child(second_child_window)

class Third():
    def __init__(self, master):
        self.master = master
        self.master.geometry("300x300")
        self.master.title("Child 2 of Main")

class Second_Child():
    def __init__(self, master):
        self.master = master
        self.master.geometry("400x300")
        self.master.title("Child of 'Child 1 of Main'")

class Login():
    def __init__(self, window):

        self.window = window
        self.window.title("Current Library")

        Label(self.window, text="Log in to use this program:").grid(row=0, column=0, sticky=W)

        self.userbox=Entry(self.window, width=20, bg="light green")
        self.userbox.grid(row=1, column=0, sticky=W)

        self.passbox=Entry(self.window, width=20, bg="light green")
        self.passbox.grid(row=2, column=0, sticky=W)

        Button(self.window, text="Submit", width=5, command=self.clicked).grid(row=3, column=0, sticky=W)

    def Focus(self):
        self.window.attributes('-topmost', 1)
        self.window.grab_set()

    def clicked(self):
        username = self.userbox.get()
        password = self.passbox.get()
        if password == "password" and username == "username":
            self.correct = True
            self.window.grab_release()
            self.window.destroy()
        else:
            pass

root_window = Tk()
root_window.iconbitmap(default='transparent.ico')
root_window.geometry("200x100")

main_window = Main(root_window)
main_window.Login()

root_window.mainloop()
Run Code Online (Sandbox Code Playgroud)

在单击按钮时调用的函数中,我可以添加 IF 语句吗?:IF 窗口对象不存在然后实例化窗口对象 ELSE 传递。

def Open1(self):
    if window2 == False:
        second_window = Toplevel(self.master)
        window2 = Second(second_window)
    else:
        pass
Run Code Online (Sandbox Code Playgroud)

如果这是正确的逻辑,那么我如何检查窗口对象是否已经创建,因为上面的方法不起作用,因为我在创建对象之前引用了该对象?

非常感谢。

Kev*_*vin 5

在 Main 的__init__.

self.child_window = None
Run Code Online (Sandbox Code Playgroud)

然后你可以检查它是否存在于Open1.

def Open1(self):
    if not self.child_window:
        self.child_window = Second(Toplevel(self.master))
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果您打算让 Second 像它自己的窗口一样运行,那么每次要创建 Second 时都必须创建一个 Toplevel 有点尴尬。按照惯例,您会创建Second的子类Toplevel,因此可以自行创建它。就像是:

class Second(Toplevel):
    def __init__(self, master, *args, **kargs):
        Toplevel.__init__(self, master, *args, **kargs)
        #rest of initialization goes here. 
        #Use `self` everywhere you previously used `self.master`.
Run Code Online (Sandbox Code Playgroud)

现在你可以这样做:

def Open1(self):
    if not self.child_window:
        self.child_window = Second(self.master)
Run Code Online (Sandbox Code Playgroud)