Python - IF function inside of the button
<p>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.</p>

<p>I'm totally clueless on how to insert the IF statement inside the button.</p>

<p>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?</p>

<pre><code>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()
</code></pre>

<p>Consider adding a method <code>checkLogin</code> and not an anonymous <code>lambda</code> 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:</p>

<pre class="lang-sql prettyprint-override"><code>SELECT 1 FROM users WHERE [Name] = ? AND [Password] = ?
</code></pre>

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

<pre><code>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")
</code></pre>

python sql tkinter