kjubus kjubus - 2 months ago 5
SQL Question

Python - IF function inside of the button

I have a problem with below code. By default it's a simple code, that switches frames. What I try to do is to modify LoginPage class to do what it says - login ;) as you can see, I have a test.db SQL database in place. It contains table users with columns: (Id INT, Name TEXT, Password TEXT)
What I need to do is input login and password, and compare it with users in database. Afterwards direct them to either LoginSuccessful or LoginFailed frames. The problem is every time I get near this class, I brake the code.

I'm totally clueless on how to insert the IF statement inside the button.

Just to clarify: It's not encrypted yet (it's just a school project), so you don't have to mention it's not safe, as I'm very aware of that :)
Anyone has any ideas?

import tkinter as tk
import sqlite3 as lite
import sys
from Crypto.Cipher import AES

con = None
con = lite.connect('test.db')
cur = con.cursor()


TITLE_FONT = ("Helvetica", 18, "bold")

class SampleApp(tk.Tk):

def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)

# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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, LoginSuccessful, LoginFailed):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame

# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")

self.show_frame("LoginPage")

def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()


class LoginPage(tk.Frame):

def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is the login page", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
inst_lbl = tk.Label(self, text = "Please enter your login credentials")
inst_lbl.pack()
pwa = tk.Label(self, text = "Login")
pwa.pack()
login = tk.Entry(self)
login.pack()
pwb = tk.Label(self, text = "pPassword")
pwb.pack()
password = tk.Entry(self)
password.pack()
button1 = tk.Button(self, text="Log in",
command=lambda: controller.show_frame("LoginSuccessful"))
button1.pack()



class LoginSuccessful(tk.Frame):

def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Login was successful!", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the Login page",
command=lambda: controller.show_frame("LoginPage"))
button.pack()


class LoginFailed(tk.Frame):

def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Login failed!", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the Login page",
command=lambda: controller.show_frame("LoginPage"))
button.pack()



if __name__ == "__main__":
app = SampleApp()
app.mainloop()

Answer

Consider adding a method checkLogin and not an anonymous lambda function which currently always opens the success screen. This method will run the parameterized SQL query to check credentials and depending on results calls the login success or failed frames:

SELECT 1 FROM users WHERE [Name] = ? AND [Password] = ?

Then, have the login button call this method. One important item is to qualify all your class variables with self., so checkLogin can use the returned LoginPage frame user input values. Below is an adjustment of the LoginPage class, the only change required:

class LoginPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.label = tk.Label(self, text="This is the login page", font=TITLE_FONT)
        self.label.pack(side="top", fill="x", pady=10)
        self.inst_lbl = tk.Label(self, text = "Please enter your login credentials")
        self.inst_lbl.pack()
        self.pwa = tk.Label(self, text = "Login")
        self.pwa.pack()
        self.login = tk.Entry(self)
        self.login.pack()
        self.pwb = tk.Label(self, text = "pPassword")
        self.pwb.pack()
        self.password = tk.Entry(self)
        self.password.pack()

        button1 = tk.Button(self, text="Log in", command=self.checkLogin)
        button1.pack()

    def checkLogin(self):
        cur.execute("SELECT 1 FROM users WHERE [Name] = ? AND [Password] = ?",
                    [self.login.get(), self.password.get()])
        result = cur.fetchone()

        if result is None:
            self.controller.show_frame("LoginFailed")
        else:
            self.controller.show_frame("LoginSuccessful")