Sticonike
Sticonike

Reputation: 59

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()

Upvotes: 0

Views: 43

Answers (2)

acw1668
acw1668

Reputation: 47085

There are few issues in your code:

  • map_image_label is local variable inside instance of EditMenu, so it cannot be accessed elsewhere. Change it to instance variable self.map_image_label instead;

  • call config() on the variable, not assignment: edit_frame.map_image_label.config(...)

  • need to use file keyword when passing the image path to PhotoImage(): map_image = PhotoImage(file=map_destination_path)

  • need to save a reference to the image, otherwise it will be garbage collected

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()

Upvotes: 1

Lajos Arpad
Lajos Arpad

Reputation: 76943

The error tells you that it did not succeed doing

config(image=map_image)

and suggests that you need to change it to

self.config(image=map_image)

This is not to be found in the code you have shared, so it must be somewhere else. You will need to find this code and prepend self. to config.

Upvotes: 0

Related Questions