【问题标题】:tkinter python: Want to close initial window and open new onetkinter python:想要关闭初始窗口并打开新窗口
【发布时间】:2021-04-20 13:38:15
【问题描述】:

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

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

【问题讨论】:

  • 我只想问如何将第二个窗口链接到第一个窗口。我已经定义了新窗口
  • 您可以使用Toplevel创建新窗口
  • 与其销毁第一个窗口,不如重用它?只需删除所有内容,然后用新窗口填充即可。

标签: python tkinter canvas label messagebox


【解决方案1】:

不要删除原来的窗口,而是重新使用它。

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

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

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

一旦你这样做了,窗口现在是空的,你可以用所有主要的应用程序小部件重新创建它。

【讨论】:

    【解决方案2】:

    这是执行此操作的一种方法:

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

    【讨论】:

      【解决方案3】:

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

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

      ----------------------------UI SETUP ---------------- ---------------

      定义密码管理器():

      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)
      

      定义创建():

      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_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, 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='创建密码:', bg=INITIAL_BG)

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

      my_entry = 入口()

      my_entry.grid(row=2, column=1,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()

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 这看起来不像是一个答案,你应该提供代码,质量很差
        • 所以我会在 login 中写 initial_window.destroy() 但是下一个窗口呢。我已经用过 window = TK()
        • 那么它应该已经存在了。如果您还不想这样做,请将第二个窗口的创建放在一个函数中并调用它
        • @Scrapper142 你能写一个更容易理解的代码示例吗?并解释什么是做什么
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-17
        • 2018-05-16
        相关资源
        最近更新 更多