我正在为我的计算机科学课程创建一个密码管理器。
我将tkinter用于用户界面,想知道在满足条件时如何交换帧。
self.logbtn = tk.Button(self,fg="red",command=self._login_btn_clicked)
它用于运行login btn模块,该模块检查输入的密码的哈希值,并将其与文本值中存储的哈希值进行比较。
def _login_btn_clicked(self): #function to check the loging
username = self.entry_username.get() #get the values from the username entry
password = self.entry_password.get() #get the values from the password entry
files = [f for f in os.listdir('.') if os.path.isfile(f)] #lists all the files in the directory
for f in files: #iterates through the files
if f==("%s.txt")%(username): #checks for a file with the same name as the username since thats how it was stored
hashedpassword = open(("%s.txt")%(username),"r").readlines()[4] #open the file and reads line 4 which is where the hashed password is stored
if hashedpassword ==(hashlib.md5(password.encode('utf-8')).hexdigest()): #checks if the entered password is the same as the hashed password
controller.show_frame(MainPage)
else:
tm.showinfo("Error","Make sure you have entered the right credentials")
在controller.show_frame(MainPage)的位置,它应该显示写在MainPage类中的新框架。
为了在框架之间进行切换,我正在堆叠所介绍的方法中使用的框架。 Switch between two frames in tkinter
整个类如下(包括处理帧切换的类)
class PasswordManager(tk.Tk):
def __init__(self,*args, **kwargs): #initialization class constantly running. Args= pass through variables kwargs=pass through libaries/dictionaries
tk.Tk.__init__(self, *args, **kwargs)
container=tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0,weight=1)
container.grid_columnconfigure(0,weight=1)
self.frames={}
for F in (LoginPage, SignUpPage, MainPage):
frame=F(container, self)
self.frames[F]=frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(LoginPage)
def show_frame(self, cont):
frame=self.frames[cont]
frame.tkraise()
class LoginPage(tk.Frame): #The log in page
def __init__(self, parent, controller): #__init__ makes sure that this class is accesibly to the whole program whenever
tk.Frame.__init__(self,parent)
self.controller=controller
self.label_username = tk.Label(self, text="Username") #label for the login page
self.label_password = tk.Label(self, text="Password")
self.entry_username = tk.Entry(self) #entrries for the login page
self.entry_password = tk.Entry(self, show="*") #show="*" is used to show that the entry only shows "*" instead of the password
self.label_username.grid(row=0, sticky="e") #to place the labels and the entries i used the .grid module in tkinter
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.checkbox = tk.Checkbutton(self, text="Keep me logged in") #tick box used to save the credentials/
self.checkbox.grid(columnspan=2)
self.logbtn = tk.Button(self, text="Login", fg="red",command=self._login_btn_clicked) #when button pressed it runs the rountine _login_btn_clicked
self.signbtn = tk.Button(self, text="Sign Up",fg="red",command=lambda: controller.show_frame(SignUpPage)) # controller is used to swap the frames
self.logbtn.grid(row=3, column=0)
self.signbtn.grid(row=3, column=1)
def _login_btn_clicked(self): #function to check the loging credentials
username = self.entry_username.get() #get the values from the username entry
password = self.entry_password.get() #get the values from the password entry
files = [f for f in os.listdir('.') if os.path.isfile(f)] #lists all the files in the directory
for f in files: #iterates through the files
if f==("%s.txt")%(username): #checks for a file with the same name as the username since thats how it was stored
hashedpassword = open(("%s.txt")%(username),"r").readlines()[4] #open the file and reads line 4 which is where the hashed password is stored
if hashedpassword ==(hashlib.md5(password.encode('utf-8')).hexdigest()): #checks if the entered password is the same as the hashed password
print("Cheese")
controller.show_frame(MainPage)
else:
tm.showinfo("Error","Make sure you have entered the right credentials")
答案 0 :(得分:0)
根据您更新的问题,我们需要修复一些问题。
首先,请确保使用PEP8样式准则定义的正确缩进。这将使其他人更容易阅读您的代码。
接下来,当您定义一个从窗口小部件继承的类时,必须定义__init__
方法和父类。
接下来,因为您需要与引发框架的方法进行交互,所以我们需要将主tkiner类传递给所有框架类。这样我们可以调用controller和show_frame方法。
这是您的示例的清理版本。如果您有任何疑问,请告诉我。注意我删除了密码检查部分,因为我没有hashlib。
import tkinter as tk
class PasswordManager(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
container = tk.Frame(self)
container.grid(row=0, column=0, sticky="nsew")
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames={}
for F in (LoginPage, SignUpPage, MainPage, MainPage):
frame=F(container, self)
self.frames[F]=frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(LoginPage)
def show_frame(self, cont):
print("test")
frame=self.frames[cont]
frame.tkraise()
class LoginPage(tk.Frame):
def __init__(self, container, controller):
tk.Frame.__init__(self)
self.controller = controller
tk.Label(self, text="Username").grid(row=0, sticky="e")
tk.Label(self, text="Password").grid(row=1, sticky="e")
self.entry_username = tk.Entry(self)
self.entry_password = tk.Entry(self, show="*")
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
self.checkbox = tk.Checkbutton(self, text="Keep me logged in")
self.checkbox.grid(columnspan=2)
tk.Button(self, text="Login", fg="red", command=lambda: self.show_frame(MainPage)).grid(row=3, column=0)
tk.Button(self, text="Sign Up", fg="red", command=lambda: self.show_frame(SignUpPage)).grid(row=3, column=1)
def show_frame(self, frame):
self.controller.show_frame(frame)
class SignUpPage(tk.Frame):
def __init__(self, container, controller):
tk.Frame.__init__(self)
tk.Label(self, text="Sign Up Page").pack()
class MainPage(tk.Frame):
def __init__(self, container, controller):
tk.Frame.__init__(self)
tk.Label(self, text="Main Page").pack()
PasswordManager().mainloop()