0

I am new to oop and I would like some assistance. I use a lambda to initalise the process of changing the frame, however I am unable to use the lambda inside of a function (method) in a class.

This is the lambda that normally works to change to the canteenpage:

lambda: controller.show_frame(CanteenPage)

I have been using this tutorial: https://www.youtube.com/watch?v=jBUpjijYtCk&t=4s&list=PLQVvvaa0QuDclKx-QpC9wntnURXVJqLyk&index=4

Original version of code :Switch between two frames in tkinter

code:

import tkinter as tk
from tkinter import ttk

class CashlessService(tk.Tk):

    def __init__(self, *args, **kwards):

        tk.Tk.__init__(self, *args, **kwards)

        tk.Tk.wm_title(self, "CashlessService")


        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 i in (LoginPage, CanteenPage, AdminPage, StudentPage):

            frame = i(container, self)

            self.frames[i] = 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):

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

        #Button to confirm ID and password
        ttk.Button(self, text="Login", command=self.LoginCheck).grid(row=4, column=1)



    def LoginCheck(self):
        login = True
        if login == True:
            lambda: controller.show_frame(CanteenPage)

class CanteenPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="canteen?", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

Sorry for the long request, I have been stuck on this for hours.

P.S no error message appears

Community
  • 1
  • 1
Mathew Wright
  • 15
  • 1
  • 7
  • 1
    With `lambda: controller.show_frame(CanteenPage)`, you just define and immediately discard a function. I think you just want `controller.show_frame(CanteenPage)` without `lambda`. Also, `if login = True` should be `if login == True`, or just `if login` – tobias_k Nov 18 '16 at 14:41
  • Also, there is no `login` defined in this code. Hopefully, you have it right, in your original code. – Lafexlos Nov 18 '16 at 14:44
  • Yeah, the login == True was just added to simplify a verification process. It is not present in my code – Mathew Wright Nov 18 '16 at 14:45
  • @tobias_k controller.show_frame(CanteenPage) - produces the following error- NameError: name 'controller' is not defined – Mathew Wright Nov 18 '16 at 14:48
  • @tobias_k This is all of the code, I think it doesn't work because it is inside the method. The lambda works when its inside of the ___init___. – Mathew Wright Nov 18 '16 at 14:54
  • your indentation for `show_frame` is incorrect. – Bryan Oakley Nov 18 '16 at 14:58
  • It is all of the code that is not tkinter widgets, imports or unrelated pages – Mathew Wright Nov 18 '16 at 14:59
  • Ah, now I see. `controller` is a parameter to the constructor. Well, then just pass that parameter on to the method call. – tobias_k Nov 18 '16 at 14:59

1 Answers1

1

You need to save a reference to the controller, then simply call it directly.

class LoginPage(tk.Frame):

    def __init__(self, parent, controller):
        self.controller = controller
        ...

    def LoginCheck(self):
        ...
        if login == True:
           self.controller.show_frame(CanteenPage)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685