pythonclasstkinterframe

access a component in a tkinter frame class from another frame class


I created a 2 Frames application in tkinter inspired by https://www.geeksforgeeks.org/how-to-change-the-tkinter-label-text/. The purpose is to import a new image by clicking on the start button, and I save it on a map.json file. When I click on the button, the frame switches. However, I want while having clicked on the button to see the image on the EditMenu Frame. Since the button is in the Home Frame, I could't find a way to access the label in EditMenu. the line edit_frame.map_image_label = config(image=map_image) gives the following error : NameError: name 'config' is not defined. Did you mean: 'self.config'? PS : The json part of the code doesn't work for now, pay no attention

   import json
   import os
   import shutil
   from tkinter import *
   from tkinter import filedialog, simpledialog
   
   
   class Main(Tk):
   
       def __init__(self, *args, **kwargs):
           Tk.__init__(self, *args, **kwargs)
           self.title("CS Memorizer")
           self.state('zoomed')
           container = 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 (Home, EditMenu):
               frame = F(container, self)
   
               self.frames[F] = frame
   
               frame.grid(row=0, column=0, sticky="nsew")
   
           frame = self.frames[Home]
           frame.tkraise()
   
       def save_image(self):
           map_name = simpledialog.askstring("Map name", "Enter the name of the map.")
           map_start_path = filedialog.askopenfilename()
           file = open(map_start_path)
           map_destination_path = os.getcwd() + "\\" + map_name + os.path.splitext(map_start_path)[1]
           shutil.copyfile(map_start_path, map_destination_path)

           with open("maps.json", "w+") as f:
               if f.read() == "":
                   f.write(json.dumps({"maps": [1]}, indent=2))
           edit_frame = self.frames[EditMenu]
           edit_frame.tkraise()
           map_image = PhotoImage(map_destination_path)

           edit_frame.map_image_label = config(image=map_image)

class Home(Frame):
   def __init__(self, parent, controller):
       Frame.__init__(self, parent)
       self.config(background="skyblue")
       maps_grid = Frame(self)
       maps_grid.pack()

       start_button = Button(maps_grid, text="Plus",  command=lambda: controller.save_image())
       start_button.grid(row=0, column=0)
   
class EditMenu(Frame):
   def __init__(self, parent, controller):
       Frame.__init__(self, parent)
       map_image_label = Label(self)
           map_image_label.pack()

Solution

  • There are few issues in your code:

    Below are the required changes:

    ...
    
    class Main(Tk):
        ...
    
        def save_image(self):
            ...
            map_image = PhotoImage(file=map_destination_path)  # use file option
    
            edit_frame.map_image_label.config(image=map_image)
            edit_frame.map_image_label.image = map_image  # use an attribute to store the reference of the image
    
    ...
    
    class EditMenu(Frame):
        def __init__(self, parent, controller):
            ...
            # use instance variable instead of local variable
            self.map_image_label = Label(self)
            self.map_image_label.pack()