Search code examples
pythontkinter

Passing variables inside class-oriented Tkinter app


its my first time coding something in tkinter and i got this problem. I was trying to do Authentification page for my app but i dont know how can i open next page when the logging was sucesful, cause i have function get_data() which collects login and password once the button is clicked but i dont know how to pass this value do different function that is comparing the variables

import tkinter as tk
from tkinter import ttk

window_width = 600
window_height = 400

class App(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self.title('Text Analyzer')
        screen_width = self.winfo_screenwidth()
        center_x = int(screen_width / 2 - window_width / 2)
        self.geometry(f'{window_width}x{window_height}+{center_x}+50')
        self.resizable(False, False)
        self.iconbitmap('ikona.ico')

        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 (AuthPage, StartPage, FrameOne, FrameTwo):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky=tk.NSEW)
        self.show_frame(AuthPage)

    def show_frame(self,cont):
        frame = self.frames[cont]
        frame.tkraise()

class AuthPage(tk.Frame):
    def __init__(self,parent,controller):

        tk.Frame.__init__(self,parent)

        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=1)
        self.grid_rowconfigure(0, weight = 1)
        self.grid_rowconfigure(1, weight=2)
        self.grid_rowconfigure(2, weight=2)
        self.grid_rowconfigure(3, weight=1)

        ttk.Label(self, text='Text Analyzer', font=("Arial", 30)).grid(columnspan=2,row=0, sticky=tk.NS)
        ttk.Label(self, text='Login: ', font=('Arial', 15)).grid(column=0, row=1, sticky=tk.E)
        ttk.Label(self, text='Hasło: ', font=('Arial', 15)).grid(column=0, row=2, sticky=tk.NE)

        wejscie1 = tk.StringVar()
        login = ttk.Entry(self, textvariable=wejscie1)
        login.grid(column=1, row=1, sticky=tk.W, ipadx=30,ipady=4)
        login.focus()

        wejscie2 = tk.StringVar()
        haslo = ttk.Entry(self, textvariable=wejscie2)
        haslo.grid(column=1, row=2, sticky=tk.NW, ipadx=30,ipady=4)

        ttk.Button(self, text='Gotowe', command=lambda: self.getdata(login,haslo)).grid(columnspan=2, row=3, sticky=tk.N, ipadx=5, ipady=3)

        if self.Auth():
            controller.show_frame(StartPage)

    def getdata(self, login, haslo):
        global logval
        logval = login.get()
        global pasval
        pasval = haslo.get()


    def Auth(self):
        login = '123'
        password = 'haslo'
        if logval == login and pasval == password:
            return True

class StartPage(tk.Frame):
    def __init__(self,parent,controller):

        tk.Frame.__init__(self,parent)

        ttk.Button(self, text='Strona 1', command=lambda: controller.show_frame(FrameOne)).pack(side=tk.LEFT)
        ttk.Button(self, text='Strona 2', command=lambda: controller.show_frame(FrameTwo)).pack(side=tk.RIGHT)

class FrameOne(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)
        ttk.Label(self, text="Frame1", font=("Helvetica", 17)).pack(fill=tk.BOTH)
        wejscie1 = tk.StringVar()
        val = ttk.Entry(self, textvariable=wejscie1)
        val.pack(side=tk.RIGHT)
        ttk.Button(self,text='Gotowe',command = lambda: self.getdata(val)).pack()

    def getdata(self,wartosc):
        napis = wartosc.get()
        print(napis)


class FrameTwo(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)
        ttk.Label(self, text="Frame2", font=("Helvetica", 17)).pack(fill=tk.BOTH)

root = App()
root.mainloop()

Solution

  • You pass & set the variables within lambda like so:

    ttk.Button(self, text='Gotowe', 
    command=lambda loginObject = login, hasloObject=haslo: self.getdata(loginObject,hasloObject))
    .grid(columnspan=2, row=3, sticky=tk.N, ipadx=5, ipady=3)
    

    Also, another small tweak this line here is called once at the beginning

        if self.Auth():
            controller.show_frame(StartPage)
    

    So I would suggest doing something like this:

    def getdata(self, login, haslo):
        # global logval ( this can be removed )
        logval = login.get()
        #global pasval
        pasval = haslo.get()
        
        if AuthPage.Auth(logval, pasval):
            controller.show_frame(StartPage)
    
    
    def Auth(logval, pasval):
        login = '123'
        password = 'haslo'
        if logval == login and pasval == password:
            return True