ttk.Treeview's width increases after hitting ttk.Radiobutton - python

I have been making this downloader app in python using tkinter and tkinter.ttk and added a recent feature in the app for the users to see a log of previous actions done by the program. It works fine, however, I recently discovered a bug.
I have a settings button which creates another Toplevel and then you can manage the default directories and change the switch the mode of the app to light or night mode or a custom theme using three ttk.Radiobuttons but whenever I hit the first two radiobuttons (the first two are responsible for switching the theme from light mode to dark mode and vise versa) my ttk.treeview's width gets added by one for no reason. the strange part is that it does not happen to the third radiobutton, responsible for making a custom mode.
I tried setting a maxsize for the log's toplevel but it is affecting the ttk.treeview itself. Why is this happening? How can I prevent this?
A simulation of my app (this is just a demonstration so I didn't write the entire theme code):
from tkinter import *
from tkinter import colorchooser
from tkinter import ttk
columns = ("Operation", "URL", "File Path", "Status", "Start Date", "End Date")
log_data = [("Download (File)", "https://www.youtube.com", "C:/Users/Mypc/Downloads/youtube.html", "Finished", "2021-03-30 13:15:30", "2021-03-30 13:15:33"),
("Format Fetch", "https://www.youtube.com/watch?v=xxNxqveseyI", "------", "Finished", "2021-03-30 13:15:30", "2021-03-30 13:15:33")]
font_color, bg_color = "black", "white"
root = Tk()
root.configure(bg=bg_color)
root.resizable(False, False)
night_on = IntVar(value=1)
style = ttk.Style()
style.configure("Treeview", rowheight=25, font=('Arial', 10))
style.configure("Treeview.Heading", font=('Arial', 10))
style.configure("TLabel", foreground=font_color, background=bg_color)
style.configure('my.TButton', font=('Helvetica', 20, 'italic'))
style.configure("TRadiobutton", foreground=font_color, background=bg_color, font=('Arial', 10))
font_color_var = StringVar(value=f"Current font color: \t {font_color}")
bg_color_var = StringVar(value=f"Current background color: \t {bg_color}")
log_top = Toplevel(root)
log_top.withdraw()
log_top.resizable(False, False)
log_fr = Frame(log_top)
log_scroll = ttk.Scrollbar(log_fr, orient=VERTICAL)
log_tree = ttk.Treeview(log_fr, selectmode="browse", yscrollcommand=log_scroll.set, height=12, columns=columns)
log_scroll.config(command=log_tree.yview)
def clear_records():
for child in log_tree.get_children():
log_tree.delete(child)
clr_log_btn = ttk.Button(log_top, text="Clear Log", takefocus=False, style="my.TButton", command=clear_records)
log_tree.column("#0", width=0, stretch=NO)
log_tree.column("Operation", width=100, anchor=CENTER)
log_tree.column("URL", width=100, anchor=CENTER)
log_tree.column("File Path", width=100, anchor=CENTER)
log_tree.column("Status", width=80, anchor=CENTER)
log_tree.column("Start Date", width=126, anchor=CENTER)
log_tree.column("End Date", width=126, anchor=CENTER)
for head in columns:
log_tree.heading(head, text=head, anchor=CENTER)
for item_indices, element in enumerate(log_data):
log_tree.insert(parent='', index=0, iid=item_indices, values=element)
log_tree.pack(side=LEFT)
log_scroll.pack(side=RIGHT, fill=Y)
clr_log_btn.pack(side=BOTTOM, fill=X)
log_fr.pack()
log_top.protocol("WM_DELETE_WINDOW", log_top.withdraw)
log_lbl = Label(root, text="Show Log", fg="blue", bg=bg_color, cursor="hand2")
def show_log(event):
if log_top.state() == "withdrawn":
log_top.deiconify()
elif log_top.state() == "normal":
log_top.focus_set()
def settings_win():
settings_top = Toplevel(root, bg=bg_color)
settings_top.resizable(False, False)
def set_night():
global bg_color, font_color
bg_color = "black"
font_color = "white"
settings_top.config(bg=bg_color)
style.configure("TLabel", foreground=font_color, background=bg_color)
style.configure("TRadiobutton", foreground=font_color, background=bg_color)
def set_light():
global bg_color, font_color
bg_color = "white"
font_color = "black"
settings_top.config(bg=bg_color)
style.configure("TLabel", foreground=font_color, background=bg_color)
style.configure("TRadiobutton", foreground=font_color, background=bg_color)
def set_custom():
global font_color, bg_color
color_fr = Toplevel(root, bg=bg_color)
color_fr.resizable(False, False)
current_font_color = ttk.Label(color_fr, textvariable=font_color_var)
current_bg_color = ttk.Label(color_fr, textvariable=bg_color_var)
def change_color(name):
global font_color, bg_color
new_color = colorchooser.askcolor()[1]
if new_color is not None:
if name == "font":
font_color = new_color
font_color_var.set(f"Current font color: \t {font_color}")
style.configure("TLabel", foreground=font_color)
style.configure("TRadiobutton", foreground=font_color)
elif name == "bg":
bg_color = new_color
bg_color_var.set(f"Current background color: \t {bg_color}")
color_fr.config(bg=bg_color)
style.configure("TLabel", background=bg_color)
style.configure("TRadiobutton", background=bg_color)
change_font = ttk.Button(color_fr, text="Change! ", command=lambda: change_color("font"),
takefocus=False)
change_bg = ttk.Button(color_fr, text="Change! ", command=lambda: change_color("bg"), takefocus=False)
current_font_color.grid(row=0, column=0, pady=(10, 0), padx=5)
change_font.grid(row=0, column=1, padx=(0, 7))
current_bg_color.grid(row=1, column=0, pady=(10, 0), padx=5)
change_bg.grid(row=1, column=1, padx=(0, 7))
night_mode = ttk.Radiobutton(settings_top, text="Night Mode", variable=night_on, value=0,
command=set_night, takefocus=False)
light_mode = ttk.Radiobutton(settings_top, text="Light Mode", variable=night_on, value=1,
command=set_light, takefocus=False)
custom_mode = ttk.Radiobutton(settings_top, text="Custom Mode", variable=night_on, value=2,
command=set_custom, takefocus=False)
night_mode.grid(row=0, column=0)
light_mode.grid(row=1, column=0)
custom_mode.grid(row=2, column=0)
log_lbl.bind("<Button-1>", show_log)
log_lbl.pack(side=LEFT, pady=30, padx=30)
settings_btn = ttk.Button(root, text="Open Settings", takefocus=False, command=settings_win)
settings_btn.pack(side=RIGHT, padx=30, pady=30)
root.focus_set()
root.mainloop()

I think I worked out a way to solve your problem. First, I minified your code to make it easier to debug:
import tkinter as tk
from tkinter import ttk
columns = ("1", "2", "3")
font_color, bg_color = "black", "white"
def change_theme():
global bg_color, font_color
# Switches the values of `bg_color` and `font_color`
bg_color, font_color = font_color, bg_color
root.config(bg=bg_color)
style.configure("TLabel", fg=font_color, bg=bg_color)
root = tk.Tk()
style = ttk.Style()
tree = ttk.Treeview(root, columns=columns)
tree.pack()
button = tk.Button(root, text="Click me", command=change_theme)
button.pack()
root.mainloop()
After looking at your code again I noticed that you had stretch=NO which is the same as stretch=False for the #0 heading. I desided to apply it to all of the heading like this:
tree.column("#0", stretch=False)
for column_name in columns:
tree.column(column_name, stretch=False)
And it solved your problem. After looking at this documentation for ttk.TreeView I noticed what it said about the stretch parameter: "If this option is True, the column's width will be adjusted when the widget is resized. The default setting is 1." From that I concluded that for some reason style.configure("TLabel", ...) changes the width of the treeview triggering all of the columns to resize.
I don't know enough about TreeView and Styles to tell you why this happens but if someone knows they can edit my answer.

Related

Only open 1 window when button clicked multiple times

I am trying to create a basic invoicing system. However i have encountered an issue as you can tell from my the title, is there any way to achieve this. I have been using a counter to determine if the window should open or not but i dont think it is right.
from tkinter import *
window = Tk()
count = 0
def openNewWindow():
global count
count = count + 1
if count == 1:
newWindow = Toplevel(window)
newWindow.title("New Window")
newWindow.geometry("800x800")
newWindow.title('test ©') # Frame title
newWindow.iconbitmap('icon4.ico') # Frame logo
if 'normal' == newWindow.state():
count = 2
else:
count = 0
width = window.winfo_screenwidth()
height = window.winfo_screenheight()
window.geometry("%dx%d" % (width, height))
bg = PhotoImage(file="bsor.gif")
label_image = Label(window, image=bg)
label_image.place(x=0, y=0)
title_label = Label(window, text="Job Management System", bg="black", fg="white")
title_label.config(font=("Courier", 70))
title_label.place(x=65, y=3)
customer_database_button = Button(window, text="Customer Database", width="23", height="2",
font=('Courier', 13, 'bold'), command=openNewWindow)
customer_database_button.grid(row=3, column=0, pady=185, padx=(110, 0))
employee_database_button = Button(window, text="Employee Database", width="23", height="2",
font=('Courier', 13, 'bold'))
employee_database_button.grid(row=3, column=1, pady=10, padx=(50, 0))
job_category_button = Button(window, text="Job Category (Pricing)", width="23", height="2",
font=('Courier', 13, 'bold'))
job_category_button.grid(row=3, column=2, pady=10, padx=(50, 0))
quote_sale_button = Button(window, text="Quotes / Sales", width="23", height="2", font=
('Courier', 13, 'bold'))
quote_sale_button.grid(row=3, column=3, pady=10, padx=(50, 0))
cash_management_button = Button(window, text="Cash Management", width="23", height="2", font=
('Courier', 13, 'bold'))
cash_management_button.grid(row=3, column=4, pady=10, padx=(50, 0))
analysis_mode_button = Button(window, text="Analysis Mode", width="23", height="2", font=
('Courier', 13, 'bold'))
analysis_mode_button.grid(row=3, column=5, pady=10, padx=(50, 0))
window.title('test') # Frame title
window.iconbitmap('icon4.ico') # Frame logo
window.mainloop()
Here is a minimal example on how to do it (works best with only one additional allowed window):
from tkinter import Tk, Toplevel, Button
def open_window(button):
button.config(state='disabled')
top = Toplevel(root)
top.transient(root)
top.focus_set()
top.bind('<Destroy>', lambda _: btn.config(state='normal'))
root = Tk()
root.geometry('300x200')
btn = Button(root, text='Open new window!', command=lambda: open_window(btn))
btn.pack(expand=True)
root.mainloop()
Just have the function disable the button and bind a <Destroy> event to the Toplevel to set the button's state back to normal. (Also you may want to use .transient on the Toplevel to make it appear above its master so that people don't forget that they haven't closed the window and wonder why they can't press the button (it will also not display additional icon in the taskbar))
Also:
I strongly advise against using wildcard (*) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2 and so on or import the whole module: import module then You can also use an alias: import module as md or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.
I strongly suggest following PEP 8 - Style Guide for Python Code. Function and variable names should be in snake_case, class names in CapitalCase. Don't have space around = if it is used as a part of keyword argument (func(arg='value')) but have space around = if it is used for assigning a value (variable = 'some value'). Have space around operators (+-/ etc.: value = x + y(except here value += x + y)). Have two blank lines around function and class declarations.

Tkinter Text widget returns ".!frame3.!frame3.!frame.!text" instead of appropriate values

I'm currently working on a project where you scan bar codes and it implements the result into an excel file. I am using tkinter to make my GUI, however, when I try to get the values from a text widget it returns the value ".!frame3.!frame3.!frame.!text". how can I fix this to get the appropriate values?
here is my code so far
import tkinter as tk
from tkinter import *
root = tk.Tk(className = "Tool Manager")
root.configure(bg='#C4C4C4')
root.title('Main Screen')
root.geometry("800x600")
main = Frame(root, bg='#C4C4C4', width = 800, height = 600)
#This is the contents of the Main Frame (screen 1)
frame_pad1 = Frame(main, bg='#C4C4C4')
frame_1 = Frame(main,bg='#C4C4C4')
frame_2 = Frame(main, bg='#C4C4C4')
frame_3 = Frame(main, bg='#C4C4C4')
min = Frame(root, bg = 'GREEN')
#mout stuffs
mout = Frame(root, bg = '#C4C4C4')
outframe_pad1 = Frame(mout, bg='#C4C4C4')
outframe_1 = Frame(mout, bg='#C4C4C4')
outframe_2 = Frame(mout, bg='#C4C4C4')
outframe_3 = Frame(mout, bg='#C4C4C4')
#code for changing screens
def raise_frame(frame):
frame.tkraise()
for frame in (main, min, mout):
frame.grid(row=1, column=1, sticky='news')
#sets frame weight for 3 rows (centers frames)
rows = 0
while rows < 3:
root.rowconfigure(rows, weight=1)
root.columnconfigure(rows,weight=1)
rows += 1
def commit_to_file():
ID = name.get()
out_list.get('1.0', 'end-1c')
print(out_list) #<----- THIS IS WHERE I'M RETURNING VALUES TO THE TERMINAL
def on_every_keyboard_input(event):
update_char_length(out_list)
#updating Line Length Information
def update_char_length(out_list):
string_in_text = out_list.get('1.0', '1.0 lineend')
string_length = len(string_in_text)
print(string_length)
if (string_length == 4):
out_list.insert(0.0, '\n')
out_list.mark_set("insert", "%d.%d" % (0,0))
#main screen formatting
area = PhotoImage(file="test.png")
areaLabel = Label(frame_1, image=area, bg='#C4C4C4')
areaLabel.pack(side=RIGHT)
mwLabel = Label(frame_2,text="this is only a test", font=("Airel", 20), bg='#C4C4C4')
mwLabel.pack(side=RIGHT)
out_button = Button(frame_3, text="Check Out", command=lambda:raise_frame(mout) , height=5, width=20, font=("Airel", 15))
out_button.pack(side=RIGHT, padx=20, pady = 4)
in_button = Button(frame_3, text="Check In", command=lambda:raise_frame(min), height=5, width=20, font=("Airel", 15))
in_button.pack(side=LEFT, padx=20, pady = 4)
#out screen formatting
name = Entry(outframe_1, font=("Airel", 15))
name.pack(side=RIGHT)
name_lbl = Label(outframe_1, text="ID Number", bg='#C4C4C4', font=("Airel", 15))
name_lbl.pack(side=LEFT)
outlist = Frame(outframe_2, bd=1, relief=SUNKEN)
outlist.pack(side=LEFT)
out_list = Text(outlist, height=30, width=40)
out_list.pack(side=RIGHT)
done_btn = Button(outframe_3, text="Done", command=commit_to_file, font=("Ariel", 15))
done_btn.pack(side=RIGHT, padx=20, pady=4)
#init to main screen
raise_frame(main)
#drawing objects for main screen
frame_pad1.pack(padx=1, pady=25)
frame_1.pack(padx=1,pady=1)
frame_2.pack(padx=10,pady=1)
frame_3.pack(padx=1, pady=80)
#drawing out screen
outframe_1.pack(padx=1, pady=1)
outframe_2.pack(padx=1,pady=1)
outframe_3.pack(padx=1, pady=1)
#calls line info update out screen
out_list.bind('<KeyRelease>', on_every_keyboard_input)
root.mainloop()
You are printing the command and not the value of it. Put the command in a variable and then print the variable.
Example: myVar = out_list.get("1.0", "end-1c") and then print(myVar)

Python, Tkinter how to give optionmenu its own windows when pressed

I have a drop down menu girded on my calculator and i have it set so that there is 3 menu items. What i want to happen is that when one of the menu items is selected it opens a toplevel window describing that item menu and each one is a different menu because they contain different things how can i code this to happen. Im stuck with setting it so that it opens different window for when a different one is slected.
def change_dropdown(*args):
top = Toplevel()
top.title("READ")
toplabel = Label(top,text= "Lmao", font = ("Helvetica", 13))
toplabel.grid()
button = Button(top, text="Dismiss", relief=FLAT, font = ("Helvetica", 10, "bold"), fg = "ghostwhite", bg = "black", width = "30", height = "2", command=top.destroy)
button.grid()
top.focus()
def popmenu():
global tkvar
tkvar = StringVar(master)
choices = {"About","Colour themes", "Contact",}
popupMenu = OptionMenu(master, tkvar, *choices)
popupMenu.grid(row = 0, column = 0, columnspan = 5, sticky=W+E+S+N)
tkvar.set("About")
tkvar.trace("w", change_dropdown)
As far as I can understand, you want something like this...
def change_dropdown(*args):
if tkvar.get() == "About":
# open About window
elif tkvar.get() == "Contact":
# open Contact window
...., etc
Complete example
Each Toplevel window is a window like the root window and you put widgets on it just like on master.
I changed the code a bit to make it more readable from my point of view; I lifted the main window (master) code from the function. I put font specs in the beginning to make the Labels and Buttons code shorter. I changed the Dict choices to a Tuple which feels more natural. I gave the OptionMenu a width to keep it from changing size with chosen selection.
from tkinter import *
master = Tk()
master.geometry('300x150+1000+50')
info = Label(master, text='Press "p" for popup menu')
info.pack()
# Fonts
H13 = ("Helvetica", 13)
H10B = ("Helvetica", 10, "bold")
def change_dropdown(*args):
top = Toplevel()
if tkvar.get() == "About": # About window
top.title("About")
toplabel = Label(top,text= "The About window", font = H13)
toplabel.grid()
button = Button(top, text="Dismiss", relief=FLAT, font = H10B,
fg = "ghostwhite", bg = "black", width = "30",
height = "2", command=top.destroy)
button.grid()
top.focus()
elif tkvar.get() == "Contact": # Contact window
top.title("Contact")
toplabel = Label(top,text= "Contact form", font = H13)
toplabel.grid()
button = Button(top, text="Dismiss", relief=FLAT, font = H10B,
fg = "ghostwhite", bg = "black", width = "30",
height = "2", command=top.destroy)
button.grid()
top.focus()
elif tkvar.get() == "Colour themes": # Color themes window
top.title("Colour themes")
toplabel = Label(top,text= "Choose color theme", font = H13)
toplabel.grid()
button = Button(top, text="Dismiss", relief=FLAT, font = H10B,
fg = "ghostwhite", bg = "black", width = "30",
height = "2", command=top.destroy)
button.grid()
top.focus()
tkvar = StringVar(master)
def popmenu(event):
top = Toplevel()
choices = ("About","Colour themes", "Contact") # Tuple or List instead of dict
popupMenu = OptionMenu(top, tkvar, *choices)
popupMenu.config(width=15) # Otherwise width varies with option
popupMenu.grid(row = 0, column = 0, columnspan = 5, sticky=W+E+S+N)
tkvar.set("Pick one")
tkvar.trace("w", change_dropdown)
master.bind('p', popmenu)
master.mainloop()
This is a very simple interface, but if you plan on making it more complex I strongly suggest you read up on Object Oriented Python. Keeping track of globals gets difficult pretty quick.

Python canvas colour change by button

I am a python self learner. I was stuck on some practice.
My idea was to create a pop out GUI with buttons that can change the canvas colour.
from Tkinter import *
import ttk
import tkMessageBox
root = Tk()
root.title("Colour!")
canvasColor = "yellow"
def buttonRed() :
canvas = Canvas(root, bg = "red", height=100, width=100)
canvas.grid(row=0,column=2)
button = ttk.Button(root, text="Red", command = buttonRed)
button.grid(row=2,column=1)
button2 = ttk.Button(root, text ="Green", command = buttonGreen)
button2.grid(row=2,column=2)
button3 = ttk.Button(root, text="Blue", command = buttonBlue)
button3.grid(row=2,column=3)
canvas = Canvas(root, bg = canvasColor, height=200, width=200)
canvas.grid(row=0,column=2)
root.configure(background='white')
root.mainloop()
i haven't put in the green and blue button command yet, but instead of creating a new canvas when the colour button clicked, i just wanted to have the default canvas colour change.
Any help will be much appreciated!
Thanks in advance.
I think this is what you need -
from Tkinter import *
import ttk
import tkMessageBox
root = Tk()
root.title("Colour!")
canvasColor = "yellow"
def buttonRed() :
canvas.config(background="red")
def buttonGreen() :
canvas.config(background="green")
def buttonBlue() :
canvas.config(background="blue")
button = ttk.Button(root, text="Red", command = buttonRed)
button.grid(row=2,column=1)
button2 = ttk.Button(root, text ="Green", command = buttonGreen)
button2.grid(row=2,column=2)
button3 = ttk.Button(root, text="Blue", command = buttonBlue)
button3.grid(row=2,column=3)
canvas = Canvas(root, bg = canvasColor, height=200, width=200)
canvas.grid(row=0,column=2)
#canvas.config(background="black")
root.configure(background='white')
root.mainloop()

Tkinter - How to display image when clicking a button?

First time here so forgive me as this is my FIRST attempt at making a silly GUI game (if you want to call it that). I'm trying to get the user to click a button and the image of their selection pops up. I can't seem to figure out how to get the image to pop up though.
Image does show if I run it separately.
My code:
from Tkinter import *
root = Tk()
class PokemonClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text="Welcome! Pick your Pokemon!",
bg="Black", fg="White")
self.WelcomeLabel.pack(fill=X)
self.CharButton = Button(root, text="Charmander", bg="RED", fg="White",
command=self.CharClick)
self.CharButton.pack(side=LEFT, fill=X)
self.SquirtButton = Button(root, text="Squirtle", bg="Blue", fg="White")
self.SquirtButton.pack(side=LEFT, fill=X)
self.BulbButton = Button(root, text="Bulbasaur", bg="Dark Green",
fg="White")
self.BulbButton.pack(side=LEFT, fill=X)
def CharClick(self):
print "You like Charmander!"
global CharSwitch
CharSwitch = 'Yes'
CharSwitch = 'No'
if CharSwitch == 'Yes':
CharPhoto = PhotoImage(file="Charmander.gif")
ChLabel = Label(root, image=CharPhoto)
ChLabel.pack()
k = PokemonClass(root)
root.mainloop()
This works, but the actual image no longer shows, if I keep the PhotoImage OUT of the class it will print but I want to have it print IF they click the specific button:
from Tkinter import *
root = Tk()
class PokemonClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text = "Welcome! Pick your Pokemon!", bg = "Black", fg = "White")
self.WelcomeLabel.pack(fill = X)
self.CharButton = Button(root, text = "Charmander", bg = "RED", fg = "White", command = CharClick)
self.CharButton.pack(side = LEFT, fill = X)
self.SquirtButton = Button(root, text = "Squirtle", bg = "Blue", fg = "White")
self.SquirtButton.pack(side = LEFT, fill = X)
self.BulbButton = Button(root, text = "Bulbasaur", bg = "Dark Green", fg = "White")
self.BulbButton.pack(side = LEFT, fill = X)
def CharClick():
print "You like Charmander!"
CharPhoto = PhotoImage(file = "Charmander.gif")
ChLabel = Label(root, image = CharPhoto)
ChLabel.pack()
k = PokemonClass(root)
root.mainloop()
You need to maintain a reference to your PhotoImage object. Unfortunately there is an inconsistency in tkinter in that attaching a Button to a parent widget increments the reference count, but adding an image to a widget does not increment the reference count. As a consequence at the moment the CharPhoto variable goes out of scope at the end of the function CharClick, the number of reference to the PhotoImage falls to zero and the object is made available for garbage collection.
If you keep a reference to the image somewhere, it will appear. When you kept it globally it remained in scope for the entire script and hence appeared.
You can keep a reference to it in the PokemonClass object or in the Label widget.
Below is the later of those options
from Tkinter import *
root = Tk()
class PokemonClass(object):
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.WelcomeLabel = Label(root, text="Welcome! Pick your Pokemon!",
bg="Black", fg="White")
self.WelcomeLabel.pack(fill=X)
self.CharButton = Button(root, text="Charmander", bg="RED", fg="White",
command=self.CharClick)
self.CharButton.pack(side=LEFT, fill=X)
self.SquirtButton = Button(root, text="Squirtle", bg="Blue", fg="White")
self.SquirtButton.pack(side=LEFT, fill=X)
self.BulbButton = Button(root, text="Bulbasaur", bg="Dark Green",
fg="White")
self.BulbButton.pack(side=LEFT, fill=X)
def CharClick(self):
print "You like Charmander!"
global CharSwitch
CharSwitch = 'Yes'
CharPhoto = PhotoImage(file="Charmander.gif")
ChLabel = Label(root, image=CharPhoto)
ChLabel.img = CharPhoto
ChLabel.pack()
CharSwitch = 'No'
k = PokemonClass(root)
root.mainloop()
The solution which helped me is just simply declaring all the image variables on the next line after 'root = Tk()'. Doing so won't spoil your code or anything.

Categories

Resources