如何从另一个类返回条目值?

时间:2019-09-27 12:26:56

标签: python tkinter

我试图从另一个类的Entry小部件返回一个值。

我的想法是,当用户成功登录后,欢迎屏幕将显示刚登录的用户名。

我尝试使用此功能:

    self.userLogged = Label(main, text = self.entry_username.get())
    self.userLogged.pack()

我尝试从self.entry.entry_username.get()类链接> login。但是这里是错误代码:

AttributeError: 'App' object has no attribute 'entry_username'

我要去哪里了?

这是完整的代码:

from tkinter import *
import tkinter.ttk as ttk


class App():
    def __init__(self,master):


        notebook = ttk.Notebook(master)
        notebook.pack(expand = 1, fill = "both")

        #Frames
        main = ttk.Frame(notebook)


        notebook.add(main, text='Welcome Screen')




        self.userLogged = Label(main, text = self.entry_username.get())
        self.userLogged.pack()





###################################################################################################################################
                                                        ##USERS##
###################################################################################################################################
class login(Frame):
    def __init__(self, master):
        super().__init__(master)

        self.label_username = Label(self, text="Username: ",font=("bold",16))
        self.label_password = Label(self, text="Password: ",font=("bold",16))

        self.entry_username = Entry(self, font = ("bold", 14))
        self.entry_password = Entry(self, show="*", font = ("bold", 14))



        self.label_username.grid(row=0, sticky=E)
        self.label_password.grid(row=1, sticky=E)
        self.entry_username.grid(row=0, column=1)
        self.entry_password.grid(row=1, column=1)

        self.logbtn = Button(self, text="Login", font = ("bold", 10), command=self._login_btn_clicked)
        self.logbtn.grid(columnspan=2)

        self.pack()


    def _login_btn_clicked(self):
        # print("Clicked")
        username = self.entry_username.get()
        password = self.entry_password.get()

        # print(username, password)
        account_list = [line.split(":", maxsplit=1) for line in open("passwords.txt")]
        # list of 2-tuples. Usersnames with colons inside not supported.
        accounts = {key: value.rstrip() for key, value in account_list}
        # Convert to dict[username] = password, and slices off the line ending.
        # Does not support passwords ending in whitespace.

        if accounts[username] == password:
            self.label_username.grid_forget()
            self.label_password.grid_forget()
            self.entry_username.grid_forget()
            self.entry_password.grid_forget()
            self.logbtn.grid_forget()
            self.pack_forget()
            app = App(root)
        else:
            print("error")





root = Tk()
root.minsize(950, 450)
root.title("test")

lf = login(root)
root.mainloop()

2 个答案:

答案 0 :(得分:0)

首先,您应该将类​​名从class login(Frame)更改为class Login(Frame)

在修复它之前,您从App调用了登录功能,但是您需要调用Login类并使用它。

class App:
    def __init__(self, master):
        notebook = ttk.Notebook(master)
        notebook.pack(expand=1, fill="both")

        # Frames
        main = ttk.Frame(notebook)

        notebook.add(main, text='Welcome Screen')

        # `entry_username.get()` method is owned by the Login class,
        # so you need to call from not `self(App class)` but `login(Login class)`.
        login = Login(master)  # Call Login class
        self.userLogged = Label(main, text=login.entry_username.get())  
        self.userLogged.pack()

有了此修复程序,我可以调用“欢迎”屏幕。

答案 1 :(得分:0)

在tkinter中使用多个类时,通常最好对主窗口和框架使用类继承。这使我们可以使用self.master在类之间进行交互。

这表示您需要更改一些内容。您在不需要的地方使用self,应该做import tkinter as tk以防止方法被覆盖。

我已经在您的代码中添加了一个类,因此我们在根窗口中使用一个类。然后在登录屏幕上使用一类,然后在登录后使用一类用于框架。

import tkinter as tk
import tkinter.ttk as ttk


class NotebookFrame(tk.Frame):
    def __init__(self, username):
        super().__init__()
        notebook = ttk.Notebook(self)
        notebook.pack(expand=1, fill="both")
        main = ttk.Frame(notebook)
        notebook.add(main, text='Welcome Screen')
        tk.Label(main, text=username).pack()


class Login(tk.Frame):
    def __init__(self):
        super().__init__()
        tk.Label(self, text="Username: ", font=("bold", 16)).grid(row=0, sticky='e')
        tk.Label(self, text="Password: ", font=("bold", 16)).grid(row=1, sticky='e')
        self.entry_username = tk.Entry(self, font=("bold", 14))
        self.entry_password = tk.Entry(self, show="*", font=("bold", 14))
        self.entry_username.grid(row=0, column=1)
        self.entry_password.grid(row=1, column=1)
        tk.Button(self, text="Login", font=("bold", 10), command=self.master._login_btn_clicked).grid(columnspan=2)


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("test")
        self.minsize(950, 450)
        self.login_frame = Login()
        self.login_frame.pack()

    def _login_btn_clicked(self):
        username = self.login_frame.entry_username.get()
        password = self.login_frame.entry_password.get()
        account_list = [line.split(":", maxsplit=1) for line in open("passwords.txt")]
        accounts = {key: value.rstrip() for key, value in account_list}
        if accounts[username] == password:
            self.login_frame.destroy()
            NoteFrame = NotebookFrame(username)
            NoteFrame.pack()
        else:
            print("error")


if __name__ == "__main__":
    App().mainloop()