Python Tkinter Closing Windows [duplicate] - python

This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 2 years ago.
In creating a Python Tkinter program, I wish to create a button that will close the program. I have tried the
#with master = Tk()
master.quit()
method. And it did absolutely nothing to my program - apart from stopping anything from working, although I received no Tracebacks.
The other method I have tried is:
#with master = Tk()
master.destroy()
This again did nothing to my program - it did give me a traceback error though which was:
_tkinter.TclError: can't invoke "button" command: application has been destroyed
My full code is:
from tkinter import *
master = Tk()
exitbutton = Button(master,text="Exit",(all the other personalization stuff here),command=(master.quit()))
#or I used master.destroy() in the command area.
exitbutton.grid(column=0,row=0)
None of the above methods have worked.
Many Thanks
(For the future)

You must pass the function's name rather than as a callable:
from tkinter import *
master = Tk()
exitbutton = Button(master,text="Exit",command=master.destroy)##dont include the parentheses
##or I used master.destroy() in the command area.
exitbutton.grid(column=0,row=0)
This should fix your problem.

Problem:
The only problem is that you are using parentheses() while passing the function(exit or destroy) to the Button as a command, Which causes it to be executed at the point where it is defined.
Solution:
The solution is to remove the parentheses() while passing the function(exit or destroy) to the Button as a command.
Fixed Code:
from tkinter import *
master = Tk()
exitbutton = Button(master, text="Exit", command=master.quit) # you can also use master.destroy
exitbutton.grid(column=0, row=0)
master.mainloop()
Tip:
As importing all(*) is not a good practice, you should import tkinter as tk
or as anything you want. The only change you will is to add tk. before each object belonging to tkinter.
Then your code will be as follows.
Best Practice:
import tkinter as tk
master = tk.Tk()
exitbutton = tk.Button(master, text="Exit", command=master.quit) # you can also use master.destroy
exitbutton.grid(column=0, row=0)
master.mainloop()

You want to pass a function object into the command keyword, so don't use parentheses. Also you should be using the destroy function for TKinter.
exitbutton = Button(master,text="Exit",(all the other personalization stuff here),command=master.destroy)

Related

How do I keep a label changed for just a few seconds [duplicate]

I am trying to delete text inside a text box after waiting 5 seconds, but instead the program wont run and does sleep over everything else. Also is there a way for me to just make my textbox sleep so i can run other code while the text is frozen?
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.insert(END, 'This is a test')
sleep(5)
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
empty_textbox()
root.mainloop()
You really should be using something like the Tkinter after method rather than time.sleep(...).
There's an example of using the after method at this other stackoverflow question.
Here's a modified version of your script that uses the after method:
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
textbox.insert(END, 'This is a test')
textbox.after(5000, empty_textbox)
root.mainloop()
You can emulate time.sleep in tkinter. For this we still need to use the .after method to run our code alongside the mainloop, but we could add readability to our code with a sleep function. To add the desired behavior, tkinter provides another underestimated feature, wait_variable. wait_variable stops the codeblock till the variable is set and thus can be scheduled with after.
def tksleep(t):
'emulating time.sleep(seconds)'
ms = int(t*1000)
root = tk._get_default_root('sleep')
var = tk.IntVar(root)
root.after(ms, var.set, 1)
root.wait_variable(var)
Real world examples:
update a Label to display a clock while-loop
animated writing nested for-loops
Limitation:
tkinter does not quit while tksleep is used.
Make sure there is no pending tksleep by exiting the application.
Using tksleep casually can lead to unintended behavior
UPDATE
TheLizzard worked out something superior to the code above here. Instead of tkwait command he uses the mainloop and this overcomes the bug of not quitting the process as described above, but still can lead to unintended output, depending on what you expect:
import tkinter as tk
def tksleep(self, time:float) -> None:
"""
Emulating `time.sleep(seconds)`
Created by TheLizzard, inspired by Thingamabobs
"""
self.after(int(time*1000), self.quit)
self.mainloop()
tk.Misc.tksleep = tksleep
# Example
root = tk.Tk()
root.tksleep(2)

Need Help tkinker [duplicate]

This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 2 years ago.
I'm trying to make a program that hides and shows all my desktop files (mac) by executing defaults write com.apple.finder CreateDesktop false #or 'true' to show my files
killall Finder
I'm using tkinker to make a gui
but everytime I execute my code, it shows all my files(without me doing anything) then when I request it to hide all my files it did, but it doesn't show them again.
Code:
import os
import tkinter as tk
def hide():
os.system("defaults write com.apple.finder CreateDesktop false")
os.system("killall Finder")
def show():
os.system("defaults write com.apple.finder CreateDesktop true")
os.system("killall Finder")
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
button = tk.Button(frame,
text="Hide",
fg="red",
command=hide)
button.pack(side=tk.LEFT)
slogan = tk.Button(frame,
text="Show",
fg="blue",
command=show())
slogan.pack(side=tk.RIGHT)
root.mainloop()
Change slogan to below:
slogan = tk.Button(frame,text="Show",fg="blue",command=show)
When you say command=show(), you are calling the function and hence it gets executed without you clicking the button, so instead remove the paranthesis and it will solve the problem.
Hope it cleared your doubt, if any errors do let me know
Cheers

Python Sleep Function Issue [duplicate]

I am trying to delete text inside a text box after waiting 5 seconds, but instead the program wont run and does sleep over everything else. Also is there a way for me to just make my textbox sleep so i can run other code while the text is frozen?
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.insert(END, 'This is a test')
sleep(5)
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
empty_textbox()
root.mainloop()
You really should be using something like the Tkinter after method rather than time.sleep(...).
There's an example of using the after method at this other stackoverflow question.
Here's a modified version of your script that uses the after method:
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
textbox.insert(END, 'This is a test')
textbox.after(5000, empty_textbox)
root.mainloop()
You can emulate time.sleep in tkinter. For this we still need to use the .after method to run our code alongside the mainloop, but we could add readability to our code with a sleep function. To add the desired behavior, tkinter provides another underestimated feature, wait_variable. wait_variable stops the codeblock till the variable is set and thus can be scheduled with after.
def tksleep(t):
'emulating time.sleep(seconds)'
ms = int(t*1000)
root = tk._get_default_root('sleep')
var = tk.IntVar(root)
root.after(ms, var.set, 1)
root.wait_variable(var)
Real world examples:
update a Label to display a clock while-loop
animated writing nested for-loops
Limitation:
tkinter does not quit while tksleep is used.
Make sure there is no pending tksleep by exiting the application.
Using tksleep casually can lead to unintended behavior
UPDATE
TheLizzard worked out something superior to the code above here. Instead of tkwait command he uses the mainloop and this overcomes the bug of not quitting the process as described above, but still can lead to unintended output, depending on what you expect:
import tkinter as tk
def tksleep(self, time:float) -> None:
"""
Emulating `time.sleep(seconds)`
Created by TheLizzard, inspired by Thingamabobs
"""
self.after(int(time*1000), self.quit)
self.mainloop()
tk.Misc.tksleep = tksleep
# Example
root = tk.Tk()
root.tksleep(2)

timer.sleep for loop inputs text into tkinter Text widget all at once instead of iterating [duplicate]

I am trying to delete text inside a text box after waiting 5 seconds, but instead the program wont run and does sleep over everything else. Also is there a way for me to just make my textbox sleep so i can run other code while the text is frozen?
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.insert(END, 'This is a test')
sleep(5)
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
empty_textbox()
root.mainloop()
You really should be using something like the Tkinter after method rather than time.sleep(...).
There's an example of using the after method at this other stackoverflow question.
Here's a modified version of your script that uses the after method:
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
textbox.insert(END, 'This is a test')
textbox.after(5000, empty_textbox)
root.mainloop()
You can emulate time.sleep in tkinter. For this we still need to use the .after method to run our code alongside the mainloop, but we could add readability to our code with a sleep function. To add the desired behavior, tkinter provides another underestimated feature, wait_variable. wait_variable stops the codeblock till the variable is set and thus can be scheduled with after.
def tksleep(t):
'emulating time.sleep(seconds)'
ms = int(t*1000)
root = tk._get_default_root('sleep')
var = tk.IntVar(root)
root.after(ms, var.set, 1)
root.wait_variable(var)
Real world examples:
update a Label to display a clock while-loop
animated writing nested for-loops
Limitation:
tkinter does not quit while tksleep is used.
Make sure there is no pending tksleep by exiting the application.
Using tksleep casually can lead to unintended behavior
UPDATE
TheLizzard worked out something superior to the code above here. Instead of tkwait command he uses the mainloop and this overcomes the bug of not quitting the process as described above, but still can lead to unintended output, depending on what you expect:
import tkinter as tk
def tksleep(self, time:float) -> None:
"""
Emulating `time.sleep(seconds)`
Created by TheLizzard, inspired by Thingamabobs
"""
self.after(int(time*1000), self.quit)
self.mainloop()
tk.Misc.tksleep = tksleep
# Example
root = tk.Tk()
root.tksleep(2)

tkinter and time.sleep

I am trying to delete text inside a text box after waiting 5 seconds, but instead the program wont run and does sleep over everything else. Also is there a way for me to just make my textbox sleep so i can run other code while the text is frozen?
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.insert(END, 'This is a test')
sleep(5)
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
empty_textbox()
root.mainloop()
You really should be using something like the Tkinter after method rather than time.sleep(...).
There's an example of using the after method at this other stackoverflow question.
Here's a modified version of your script that uses the after method:
from time import time, sleep
from Tkinter import *
def empty_textbox():
textbox.delete("1.0", END)
root = Tk()
frame = Frame(root, width=300, height=100)
textbox = Text(frame)
frame.pack_propagate(0)
frame.pack()
textbox.pack()
textbox.insert(END, 'This is a test')
textbox.after(5000, empty_textbox)
root.mainloop()
You can emulate time.sleep in tkinter. For this we still need to use the .after method to run our code alongside the mainloop, but we could add readability to our code with a sleep function. To add the desired behavior, tkinter provides another underestimated feature, wait_variable. wait_variable stops the codeblock till the variable is set and thus can be scheduled with after.
def tksleep(t):
'emulating time.sleep(seconds)'
ms = int(t*1000)
root = tk._get_default_root('sleep')
var = tk.IntVar(root)
root.after(ms, var.set, 1)
root.wait_variable(var)
Real world examples:
update a Label to display a clock while-loop
animated writing nested for-loops
Limitation:
tkinter does not quit while tksleep is used.
Make sure there is no pending tksleep by exiting the application.
Using tksleep casually can lead to unintended behavior
UPDATE
TheLizzard worked out something superior to the code above here. Instead of tkwait command he uses the mainloop and this overcomes the bug of not quitting the process as described above, but still can lead to unintended output, depending on what you expect:
import tkinter as tk
def tksleep(self, time:float) -> None:
"""
Emulating `time.sleep(seconds)`
Created by TheLizzard, inspired by Thingamabobs
"""
self.after(int(time*1000), self.quit)
self.mainloop()
tk.Misc.tksleep = tksleep
# Example
root = tk.Tk()
root.tksleep(2)

Categories