In this code I am displaying a window with a label and two buttons, the user can read the file path currently in use in the label and decide if he wants to change it or continue with the buttons.
If he wants to change the path then I change the value inside the textvariable inside the label. The issue is when I do this for example 3 times, then I have to kill the program manually pressing CTRL C 3 times. If I do it once then I only need to do it once, like there is something preventing the program to terminate. Thanks for the help.
def select_file():
#OPEN TKINTER DIALOG LETTING ME TO CHOOSE A FILE AND RETURNS ITS PATH.
tkinter.Tk().withdraw() # prevents an empty tkinter window from appearing
folder_path = filedialog.askopenfilename()
return folder_path
def change_file():
file_path = select_file()
with open(os.path.expanduser('~/Documents/Squad Generator/excel_file_path.txt'), 'w') as f:
f.write(file_path)
#WRITES THE FILE PATH IN THE VARIABLE AND CHANGES THE LABEL
var.set(file_path)
def homepage():
app.geometry("450x200")
app.title("Squad Generator")
label_1 = tkinter.Label(master=app, justify=tkinter.LEFT,textvariable=var, font =
("JetBrains Mono", 15))
label_1.grid(row=0, column=0, columnspan=2, padx=20, pady=(20, 0), sticky="nsew")
button1 = tkinter.Button(master=app, text="Continua", command=main)
button1.grid(row=1, column=0, padx=20, pady=20, sticky="ew")
#BUTTON CAUSING THE ISSUE.
button2 = tkinter.Button(master=app, command=change_file, text="Cambia file")
button2.grid(row=1, column=1, padx=0, pady=20, sticky="ew")
#CREATING APP MAINLOOP
app.mainloop()
if __name__ == '__main__':
app = tkinter.Tk()
var = tkinter.StringVar(None, check_path_file())
homepage()
CodePudding user response:
I've reorganized your application a bit. I've wrapped everything in a basic class named App
which serves as the root of your application. This should work as expected and keep everything contained within a single instance of Tk
.
import tkinter
from tkinter.filedialog import askopenfilename
class App(tkinter.Tk): # the App class inherits from Tk
def __init__(self):
super().__init__() # initialize Tk
self.geometry("450x200")
self.title("Squad Generator")
self.label_var=tkinter.StringVar(self, 'Select a file path')
self.label_1 = tkinter.Label(
master=self,
justify=tkinter.LEFT,
textvariable=self.label_var,
font=("JetBrains Mono", 15)
)
self.label_1.grid(row=0, column=0, columnspan=2, padx=20, pady=(20, 0), sticky="nsew")
self.button1 = tkinter.Button(master=self, text="Continua", command=main)
self.button1.grid(row=1, column=0, padx=20, pady=20, sticky="ew")
self.button2 = tkinter.Button(
master=self,
command=self.change_file,
text="Cambia file"
)
self.button2.grid(row=1, column=1, padx=0, pady=20, sticky="ew")
self.change_file() # call this function when the app starts
def change_file(self):
file_path = askopenfilename()
if file_path: # if a file is selected and not cancelled by the user
input_file = '~/Documents/Squad Generator/excel_file_path.txt'
with open(os.path.expanduser(input_file), 'w') as f:
f.write(file_path) # write out 'file_path' to the 'input_file'
#WRITES THE FILE PATH IN THE VARIABLE AND CHANGES THE LABEL
self.label_var.set(file_path)
else:
self.label_var.set('Select a file path') # fallback text if user cancels
if __name__ == '__main__':
app = App() # instantiate your App class
app.mainloop() # run the app
If you're not familiar with classes, the word self
here can be confusing. All you need to know is that self
refers to the App
class. So any widgets you define within that class, like button1
have self
as their master - i.e., they are children of the App
class!
Also, any methods you define within the class (like change_file(self)
) will be callable within the class via self.change_file
, and will have access to any variables in the class, like self.label_var
!
CodePudding user response:
From what I see you just did
app.destroy()
But you actually need to do
app.master.destroy()
With the first line you're just destroying the current frame, not the the top level container.