0

I am trying to make a GUI app for a class I'm teaching.

I have to have several frames that can be raised above on another. To do that I slightly modified the code from this link:

Switch between two frames in tkinter

However, within the Frame and Class called "Terrain" my Save button inside the frame will not call on the MySave function within the Terrain class. I would appreciate any help.

Most of the code works fine. The buttonsave variable is where the problem begins.

import sys

if sys.version_info.major >= 3:
    from tkinter import *
    import tkinter as tk
else:
    from Tkinter import *
    import Tkinter as tk

from PIL import ImageTk, Image

import os

os.getcwd()
print(os.getcwd())

root = Tk()

class Container:
    def __init__(self, master):
        container = Frame(master)
        container.grid()
        
        self.frames = {}
        for F in (Terrain, Survey, Excavate):
            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("Terrain")

    def show_frame(self, page_name):
        #Show a frame for the given page name
        frame = self.frames[page_name]
        frame.tkraise()
        print("Oh Boy")

        
        
        
class Terrain(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        bpream = ".\\Images\\Buttons\\"
        farrow = bpream+"farrow"+".png"
        #farrow = farrow.resize((25, 25), Image.ANTIALIAS)
        self.farrow = PhotoImage(file = farrow)
        fbutton = tk.Button(self, image = self.farrow, borderwidth = 0, command=lambda: controller.show_frame("Survey"))        
        fbutton.grid(row = 12, column = 2)
       
         # The Name, Answer and Save Boxes    
        ans = tk.Text(self, width = 30, height = 20, borderwidth = 5)
        ans.grid(row = 1, column = 7, columnspan = 2, rowspan = 5, padx = 10, pady = 10)
        ans.insert(1.0, "Type your answers here")

        buttonsave = tk.Button(self, text = "Save", padx = 20, pady = 5, command = lambda:[self.mySave, self.switch])
        buttonsave.grid(row = 6, column = 8)

        buttonedit = tk.Button(self, text = "Edit", padx = 20, pady = 5, command = self.switch, state = 'disabled')
        buttonedit.grid(row = 6, column = 7)   
        
    # Save the Name and Answers
    def mySave(self):
        print("Why you click me?")
        answer = ans.get("1.0",'end-1c')
        namer = name.get("1.0",'end-1c')
        print(namer)
        print(answer)
        
    #Toggle the Edit and Save Functions
        
    def switch(self):
        print("Who did this?")
        if  buttonsave['state'] == 'normal':
            buttonsave['state'] = 'disabled'
            buttonedit['state'] = 'normal'
            ans['state'] = 'disabled'
            name['state'] = 'disabled'
        else:
            buttonsave['state'] = 'normal'
            buttonedit['state'] = 'disabled'
            ans['state'] = 'normal'
            name['state'] = 'normal'
                        
        
        
        
        
        
        
class Survey(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        bpream = ".\\Images\\Buttons\\"
        farrow = bpream+"farrow"+".png"
        #farrow = farrow.resize((25, 25), Image.ANTIALIAS)
        self.farrow = PhotoImage(file = farrow)
        self.fbutton = tk.Button(self, image = self.farrow, borderwidth = 0, command=lambda: controller.show_frame("Excavate"))        
        self.fbutton.grid(row = 12, column = 2)
        barrow = bpream+"barrow"+".png"
        #barrow = barrow.resize((25, 25), Image.ANTIALIAS)
        self.barrow = PhotoImage(file = barrow)
        self.bbutton = tk.Button(self, image = self.barrow, borderwidth = 0, command=lambda: controller.show_frame("Terrain"))        
        self.bbutton.grid(row = 12, column = 1)  
        
class Excavate(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        bpream = ".\\Images\\Buttons\\"
        barrow = bpream+"barrow"+".png"
        #barrow = barrow.resize((25, 25), Image.ANTIALIAS)
        self.barrow = PhotoImage(file = barrow)
        self.bbutton = tk.Button(self, image = self.barrow, borderwidth = 0, command=lambda: controller.show_frame("Survey"))        
        self.bbutton.grid(row = 12, column = 1)       
        
exc = Container(root)        
root.mainloop() 
  • Your code would be much easier to understand and debug if you created a proper function rather than try to call two functions in a lambda. – Bryan Oakley Aug 10 '20 at 19:46
  • As far as I can tell @BryanOakley, it doesn't matter if its just one or two functions in that I'm trying to call. The button just won't call. How would you recommend I make a proper function? – DimtheQuiet Aug 10 '20 at 20:39
  • The button _is_ calling the lambda. The lambda doesn't do anything. If it called a function rather than a lambda you could add a print statement to prove it was being called. The problem is, the lambda does `[self.mySave, self.switch]`. `self.mySave` does nothing. `self.mySave()` calls a function. I don't know how to answer the question of how to make a proper function. You clearly know how to make functions, and you know how to attach functions to buttons, so I'm not sure what I can add that would tell you anything new. – Bryan Oakley Aug 10 '20 at 20:54
  • Well @BryanOakley you actually just answered my need. All I needed were the parentheses in the command = self.mySave(). Its working wonderfully. Would you like to see the final code? Thank you for your help :) – DimtheQuiet Aug 10 '20 at 21:14

0 Answers0