tkinter python:想要关闭初始窗口并打开新窗口

问题描述

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

# ---------------------------- 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,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()

解决方法

这是一种方法:

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 是主窗口,所以它继承自 Tk 并在启动时被撤回,也可以颠倒这一点,以便 MainWindow 继承 Toplevel,然后使登录窗口继承自 Tk 但 Toplevel 通常是一个父母是 Tk 的人,这样就没有意义了。否则该选项也有效。然而,一个小缺点是,当从 LoginWindow 移动到 MainWindow 时,任务栏中的图标会移动一点,因此为了避免这种情况,您也可以只使用框架并在它们之间切换。

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

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

from tkinter import Tk,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,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()
,

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

创建一个函数或类来创建登录窗口,另一个来创建主程序。调用该函数以创建登录窗口。当用户登录时,销毁登录窗口的所有小部件并为主程序创建小部件。

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

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

执行此操作后,窗口现在是空的,您可以使用所有主应用程序小部件重新创建它。

,

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

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

----------------------------在用户界面设置之后 ---------------- ---------------

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,fg='white',highlightcolor='red')
website_data.focus()
website_data.grid(row=1,column=1,sticky='w')

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

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

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

password_data = Entry(width=32,fg='white')
password_data.grid(row=3,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,columnspan=2)

search_button = Button(text='Search',command=lambda: search_record(website_data),highlightthickness=0)
search_button.grid(row=1,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)

定义创建():

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('新页面')

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,bg=INITIAL_BG)

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

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

my_label = Label(text='创建密码:',bg=INITIAL_BG)

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

my_entry = Entry()

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

my_entry.focus()

error_label = Label(text=" * 密码应至少有 8 个字符",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)

试试:

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()

,

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