A few other things that weren't mentioned so far: In a few places, you do something like this: f"{adjust}{os.path.basename(self.p).strip('.jpg') + ' ' + username}" Why not simply: f"{adjust}{os.path.basename(self.p).strip('.jpg')} {username}" Speaking of which, your use of `str.strip` doesn't behave the way you think it does. Take a look: >>> help(str.strip) Help on method_descriptor: strip(self, chars=None, /) Return a copy of the string with leading and trailing whitespace remove. If chars is given and not None, remove characters in chars instead. >>> In your case, the optional `chars` parameter is not `None`, it's `".jpg"`. That means it will remove any of the characters specified in `chars`. Not only that, but since you're using `str.strip` instead of `str.rstrip`, you're potentially removing those characters not just from the back, but from the front as well. For example: >>> "john_help.jpg".strip(".jpg") 'ohn_hel' >>> Definitely not the desired output in your case. Using `str.rstrip` would strip only from the back of the string, but it still wouldn't give you the desired result: >>> "john_help.jpg".rstrip(".jpg") 'john_hel' >>> If you're using Python 3.4+, you're better of using `pathlib` anyway instead of all that `os.path` stuff: >>> from pathlib import Path >>> Path("root/dir/sub/file.jpg").stem 'file' >>> I would also suggest using an `enum.Enum` to represent the possible values / options / states of your `tk.Radiobutton`s. It prevents you from "stringify-ing" the options or doing something like this: val = item.get() #radiobutton value if val == 2: # checks if yes cells[1].text = "*" elif val == 1: # checks if no cells[2].text = "*" elif val == 0: # checks if N/A cells[3].text = "*" Here's how I might set up a `tk.Radiobutton` using an enum: import tkinter as tk class Application(tk.Tk): from enum import Enum class RadioOption(Enum): Red = 0 Green = 1 Blue = 2 def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.title("Title") self.geometry("100x100") self.resizable(width=False, height=False) self.radio_variable = tk.Variable(None, Application.RadioOption.Red) def on_radio_variable_change(*args): print(self.radio_variable.get()) self.radio_variable.trace(mode="w", callback=on_radio_variable_change) self.radio_button_red = tk.Radiobutton( self, text="Red", variable=self.radio_variable, value=Application.RadioOption.Red, ) self.radio_button_green = tk.Radiobutton( self, text="Green", variable=self.radio_variable, value=Application.RadioOption.Green, ) self.radio_button_blue = tk.Radiobutton( self, text="Blue", variable=self.radio_variable, value=Application.RadioOption.Blue, ) self.radio_button_red.pack(anchor=tk.W) self.radio_button_green.pack(anchor=tk.W) self.radio_button_blue.pack(anchor=tk.W) def main(): application = Application() application.mainloop() return 0 if __name__ == "__main__": import sys sys.exit(main()) And one more tiny nit-pick, in a few different places you do something like this: self.open_button.grid(row=502, column=0) self.resetBtn = Button(main, text = "reset", command = reset) See how some of the keyword-arguments have additional whitespace, and others do not? Pick one style, but don't do both - personally I would remove the whitespace since that's PEP8 compliant.