【问题标题】:Python tkinter: How can I ensure only ONE child window is created onclick and not a new window every time the button is clicked?Python tkinter:如何确保每次单击按钮时只创建一个子窗口而不是新窗口?
【发布时间】:2014-09-13 04:22:06
【问题描述】:

目前正在学习 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()

在单击按钮时调用的函数内部可以添加 IF 语句吗?:如果窗口对象不存在则实例化窗口对象 ELSE 传递。

def Open1(self):
    if window2 == False:
        second_window = Toplevel(self.master)
        window2 = Second(second_window)
    else:
        pass

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

非常感谢。

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    初始化Main的__init__中的子窗口变量。

    self.child_window = None
    

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

    def Open1(self):
        if not self.child_window:
            self.child_window = Second(Toplevel(self.master))
    

    顺便说一句,如果您打算让 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`.
    

    现在你可以这样做了:

    def Open1(self):
        if not self.child_window:
            self.child_window = Second(self.master)
    

    【讨论】:

    • 另一个相关问题:当​​子窗口关闭(以红叉退出)时,如何将“None”重新分配给变量“self.child_window”?
    • 您可以注册一个在窗口关闭时调用的回调函数。请参阅this post 了解更多信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多