tkinter python: 想要关闭初始 window 并打开新的

tkinter python: Want to close initial window and open new one

我目前正在开发密码管理器,初始 window 将要求登录或创建密码。单击登录按钮后,我想关闭初始 window 并打开主密码管理器 window。这是我的代码:-

# ---------------------------- Creating password/ Login ------------------------------- #

def login():

    password = my_entry.get()
    if saved_pass == password:
        # what to write here
        pass

    else:
        # when you type wrong password.
        error_label.config(text="Password didn't Match. Try Again.", fg='red')
        # error_label.place(x=160, y=330)


def create():

    password = my_entry.get()
    if len(password) > 8 and ' ' not in password:
        error_label.config(text="Your Current Password is Saved.", fg='green')
        with open('login_password.json', 'w') as add_pass:
            json.dump(password, add_pass)

    else:
        my_entry.delete(0, END)
        error_label.config(text="Password is Too Short or Not Valid.", fg='red')

# ----------------------------Initial UI SETUP ------------------------------- #


initial_window = Tk()

initial_window.title('new page')

initial_window.geometry("460x430")

initial_window.config(padx=20, pady=20, bg=INITIAL_BG)

img = PhotoImage(file='new.png')

canvas = Canvas(width=360, height=250, highlightthickness=0, bg=INITIAL_BG)

canvas.create_image(210, 135, image=img)

canvas.grid(row=1, column=0, columnspan=2, sticky='ew')

my_label = Label(text='Create Password:', bg=INITIAL_BG)

my_label.grid(row=2, column=0, sticky='ew')

my_entry = Entry()

my_entry.grid(row=2, column=1, sticky='ew')

my_entry.focus()

error_label = Label(text=" * Password should have at least 8 characters", fg='black', bg=INITIAL_BG)

error_label.place(x=160, y=330)

save_button = Button(text='Save', width=20)

save_button.place(x=185, y=290)

try:

    with open('login_password.json') as data:
        saved_pass = json.load(data)
        save_button.config(text='Login')
        my_label.config(text='Enter Password')
        save_button.config(command=login)
        error_label.config(text='')
except (json.decoder.JSONDecodeError, FileNotFoundError):

     SAVED = False
     save_button.config(command=create)

# ----------------------------After UI SETUP ------------------------------- #

window = Tk()
window.title('Password Manager')
window.config(padx=50, pady=50, bg=AFTER_BG)
window.mainloop()

尝试initial_window.destroy()。这将关闭 window 并结束其所有进程。然后设置一个新的变量window = Tk()会打开一个新的window

这是一种方法:

from tkinter import Tk, Toplevel, Button


class MainWindow(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title('Main Window')
        self.geometry('500x300')


class LoginWindow(Toplevel):
    def __init__(self, parent):
        Toplevel.__init__(self, parent)
        self.parent = parent
        self.title('LoginWindow')
        self.geometry('500x300')
        self.protocol('WM_DELETE_WINDOW', root.quit)

        Button(self, text='Login', command=self.login).pack()

    def login(self):
        self.destroy()
        self.parent.deiconify()


if __name__ == '__main__':
    root = MainWindow()
    root.withdraw()

    login = LoginWindow(root)

    root.mainloop()

MainWindow 是主窗口window 所以它继承自Tk 并在启动时被撤回,也可以反过来使MainWindow 继承自Toplevel 然后进行登录window 从 Tk 继承,但 Toplevel 通常是父级为 Tk 的那个,所以那样做是没有意义的。否则该选项也有效。然而,一个小缺点是,当从登录窗口移动到主窗口时,任务栏中的图标会稍微移动,因此为了避免这种情况,您也可以只使用框架并在它们之间切换。

此外(我忘记了)在这种情况下,必须在 LoginWindow 中设置一个协议,告诉如果 window 关闭会发生什么。 self.protocol('WM_DELETE_WINDOW', root.quit)因为否则MainWindow仍然会在后台保留运行(如果按下右上角的X),也可以使用self.parent.destroy

这是相同的解决方案,但使用函数:

from tkinter import Tk, Toplevel, Button


def login_window(parent):

    def login():
        tp.destroy()
        parent.deiconify()

    tp = Toplevel()
    tp.title('Login Window')
    tp.geometry('500x300')
    tp.protocol('WM_DELETE_WINDOW', parent.quit)

    Button(tp, text='Login', command=login).pack()


def main_window():
    root = Tk()
    root.title('Main Window')
    root.geometry('500x300')
    root.withdraw()

    login_window(root)

    root.mainloop()


if __name__ == '__main__':
    main_window()

解决方案:- 要终止当前 Window,请使用 window_name.destroy(),然后调用一个函数并将第二个 window 的元素初始化到其中。感谢@Matiiss @Scrapper142 的指导。您可以使用按钮调用函数并使用 lambda 在其中提供一些参数。

EX- button = Button(text='click', command= lambda: function_name(arguments))

----------------------------UI SETUP 之后 ---------- ----------------------

def password_manager():

window = Tk()
window.title('Password Manager')
window.config(padx=50, pady=50, bg=AFTER_BG)

# image
logo_img = PhotoImage(file='logo.png')
canvas = Canvas(width=200, height=200, highlightthickness=0, bg=AFTER_BG)
canvas.create_image(100, 100, image=logo_img)
canvas.grid(row=0, column=1)

# website data
website_text = Label(text='Website:', bg=AFTER_BG, fg='white')
website_text.grid(row=1, column=0)

website_data = Entry(width=32, bg=AFTER_BG, fg='white', highlightcolor='red')
website_data.focus()
website_data.grid(row=1, column=1, sticky='w')

# email data
email_text = Label(text='Email/Username:', bg=AFTER_BG, fg='white')
email_text.grid(row=2, column=0)

email_data = Entry(width=51, bg=AFTER_BG, fg='white')
email_data.insert(END, 'lalitwizz21@gmail.com')
email_data.grid(row=2, column=1, columnspan=2, sticky='e')

# password data
password_text = Label(text='Password:', bg=AFTER_BG, fg='white')
password_text.grid(row=3, column=0)

password_data = Entry(width=32, bg=AFTER_BG, fg='white')
password_data.grid(row=3, column=1, sticky='w')

# button to Generate Password
password_generator_button = Button(text='Generate Password', width=14, command=lambda: password_generator(password_data))
password_generator_button.grid(row=3, column=2, sticky='e')

# button to add records
add_button = Button(text='Add', width=43, command=lambda: save_password(website_data, email_data, password_data), highlightthickness=0)
add_button.grid(row=4, column=1, columnspan=2)

search_button = Button(text='Search', width=14, command=lambda: search_record(website_data), highlightthickness=0)
search_button.grid(row=1, column=2, sticky='e')

window.mainloop()

---------------------------- 创建密码/登录------------ ------------------

定义登录():

password = my_entry.get()
if saved_pass == password:
    initial_window.destroy()
    password_manager()

else:
    # when you type wrong password.
    error_label.config(text="Password didn't Match. Try Again.", fg='red')
    # error_label.place(x=160, y=330)

def 创建():

password = my_entry.get()
if len(password) > 8 and ' ' not in password:
    error_label.config(text="Your Current Password is Saved.", fg='green')
    with open('login_password.json', 'w') as add_pass:
        json.dump(password, add_pass)

else:
    my_entry.delete(0, END)
    error_label.config(text="Password is Too Short or Not Valid.", fg='red')

-------------------------初始 UI 设置 ---------- ----------------------

initial_window = Tk()

initial_window.title('new page')

initial_window.geometry("460x430")

initial_window.config(padx=20, pady=20, bg=INITIAL_BG)

img = PhotoImage(文件='new.png')

canvas = Canvas(width=360, height=250, highlightthickness=0, bg=INITIAL_BG)

canvas.create_image(210, 135, 图片=img)

canvas.grid(行=1,列=0,列跨度=2,粘性='ew')

my_label = 标签(text='Create Password:', bg=INITIAL_BG)

my_label.grid(行=2,列=0,粘性='ew')

my_entry = 条目()

my_entry.grid(行=2,列=1,粘性='ew')

my_entry.focus()

error_label = Label(text=" * 密码至少要有8个字符", fg='black', bg=INITIAL_BG)

error_label.place(x=160, y=330)

save_button = 按钮(文本='Save', 宽度=20)

save_button.place(x=185, y=290)

尝试:

with open('login_password.json') as data:
    saved_pass = json.load(data)
    save_button.config(text='Login')
    my_label.config(text='Enter Password')
    save_button.config(command=login)
    error_label.config(text='')

除了(json.decoder.JSONDecodeError,FileNotFoundError):

 SAVED = False
 save_button.config(command=create)

initial_window.mainloop()

与其删除原来的window,不如重新使用它。

创建一个函数或class创建登录window,另一个创建主程序。调用创建登录名的函数 window。当用户登录时,销毁所有用于登录的小部件 window 并为主程序创建小部件。

如果登录 window 小部件都存在于一个框架内,这将是最简单的。然后您可以销毁框架,所有其他小部件将自动销毁。或者,您可以简单地遍历主要 window 中的所有子项以销毁它们:

for child in window.winfo_children():
    child.destroy()

完成后,window 现在是空的,您可以使用所有主要应用程序小部件重新创建它。