我试图通过def功能摧毁一个窗口到另一个,但我不断收到此错误

时间:2018-06-07 20:26:11

标签: python python-3.x tkinter

当我点击注册时会出现此错误

AttributeError: 'function' object has no attribute 'destroy'

我不明白为什么它不起作用我已经尝试了所有的东西。 我的程序目前的目标是,当我运行程序时,它以登录屏幕启动,如果我单击注册,它将关闭窗口,转到log_to_reg定义,其中显示login_screen并打开register_screen

    #importing moduels
from tkinter import *
from tkinter import messagebox
from tkinter import ttk

def login_screen():
    #adding the login screen
    login_screen = Tk()
    login_screen.geometry("400x250")
    login_screen.title("Tree Road School server")
    login_screen.resizable(False,False)
    login_screen.configure(background = "Light blue")
#adding the title label
label_title = Label(login_screen, text="LOGIN", width = '6',
                    font=('Arial', 25)).place(x=135, y= 25)

#adding the labels for loging in
label_username = Label(login_screen, text = "username: ", font=(15))\
                 .place(x=100, y= 100)
label_username1 = Label(login_screen, text = "       ", font=(15), width='13')\
                 .place(x=175, y= 100)

label_space = Label(login_screen, text = "          ", font=(15), width='13')\
                 .place(x=100, y= 120)
label_space1 = Label(login_screen, text = "       ", font=(15), width='13')\
                 .place(x=175, y= 120)

label_password = Label(login_screen, text = "password:  ", font=(15))\
                 .place(x=100, y= 130)
label_password1 = Label(login_screen, text = "       ", font=(15), width='13')\
                 .place(x=175, y= 130)

#adding the entry
username = Entry(login_screen, width = 15, bg = "White")
username.place(x=200, y=102)

#space to make it look nicer
password = Entry(login_screen, width = 15, bg = "White", show = "*")
password.place(x=200, y=132)

#adding the buttons
login_button = Button(login_screen, text = "login",
                      width = 10).place(x=100, y=175)

sign_up_button = Button(login_screen, text = "Register", 
                      width = 14, command = log_to_reg).place(x=190, y=175)

#run mainloop
login_screen.mainloop()

def register_screen():
    register_screen = Tk()
    register_screen.geometry("400x250")
    register_screen.title("Register")
    register_screen.resizable(False,False)
    register_screen.configure(background = "Light blue")

def log_to_reg():
    login_screen.destroy()
    rigister_screen()



login_screen()

1 个答案:

答案 0 :(得分:1)

您的错误的答案:

  

AttributeError:'function'对象没有属性'destroy'

您有一个名为login_screen的函数,并且您试图在该函数上调用destroy(),因此会抛出错误。

这部分是因为你将你的函数和根窗口命名为同一个东西。另一部分是因为根窗口只是函数中的局部变量,因此login_screen函数之外的函数无法在里面看到tkinter实例。

你可以使用global来管理这样的东西但是所有这些都不是最好的选择。您确实希望避免在tkinter中多次使用Tk()并避免使用global

相反,我们可以将每个项目设置为一个类,并使用tkinters Toplevel()打开注册窗口。

以下是使用grid()管理窗口中所有内容的代码的修改版本。我们还可以使用withdrow()deiconify()来管理可见的窗口。

import tkinter as tk

class Login(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.geometry("400x250")
        self.title("Tree Road School server")
        self.resizable(False,False)
        self.configure(background = "Light blue")
        self.columnconfigure(0, weight=1)
        self.columnconfigure(2, weight=1)
        self.rowconfigure(0, weight=1)
        self.rowconfigure(2, weight=1)

        center_frame = tk.Frame(self)
        center_frame.grid(row=1, column=1, sticky="nsew")

        tk.Label(center_frame, text="LOGIN", width = '6', font=('Arial', 25)).grid(row=0, column=0, columnspan=2, padx=10, pady=5)
        tk.Label(center_frame, text="username: ", font=(15)).grid(row=1, column=0, padx=10, pady=5)
        tk.Label(center_frame, text="password: ", font=(15)).grid(row=2, column=0, padx=10, pady=5)

        self.username = tk.Entry(center_frame, width=15, bg="White")
        self.username.grid(row=1, column=1, padx=10, pady=5)
        self.password = tk.Entry(center_frame, width=15, bg="White", show="*")
        self.password.grid(row=2, column=1, padx=10, pady=5)

        tk.Button(center_frame, text="login", width=10).grid(row=3, column=0, padx=10, pady=5)
        tk.Button(center_frame, text="Register", width=14, command=self.atempt_register).grid(row=3, column=1, padx=10, pady=5)
        self.mainloop()

    def atempt_register(self):
        self.withdraw()
        RegisterScreen(self, self.username.get(), self.password.get())



class RegisterScreen(tk.Toplevel):
    def __init__(self, controller, username, password):
        tk.Toplevel.__init__(self)
        self.controller = controller
        self.protocol("WM_DELETE_WINDOW", self.on_close)
        self.geometry("400x250")
        self.title("Register")
        self.resizable(False, False)
        self.configure(background = "Light blue")
        self.username = username
        self.password = password

        tk.Label(self, text=username).grid(row=0, column=0)
        tk.Label(self, text=password).grid(row=1, column=0)

    def on_close(self):
        self.controller.deiconify()
        self.destroy()


Login()