满足功能时在Tkinter中切换帧

时间:2018-11-07 17:10:18

标签: python tkinter

我正在为我的计算机科学课程创建一个密码管理器。 我将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")

1 个答案:

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