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