Reputation: 243
I'm new to TKinter
. I need to change the text of a button
and its state
when its clicked, then do some actions, and finally change again its text and state.
The problem is the changes only apply once the function has ended, skipping the first change of state and text. It never changes the Buttons
text to "loading" and the button is never disabled.
Here is the code for the problem i'm experiencing:
#!/usr/bin/env python
import tkinter as tk
import time
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack(fill=tk.BOTH, expand=1)
self.create_widgets()
def create_widgets(self):
self.master.title("CW POS")
cierre = tk.Button(
self.master,
command=self.re_imprimir_ultimo_cierre)
cierre["text"] = "foo"
cierre.pack(fill=tk.BOTH, expand=1)
self._cierre = cierre
salir = tk.Button(self.master, text="quit", command=self.salir)
salir.pack(fill=tk.BOTH, expand=1)
def salir(self):
exit()
def re_imprimir_ultimo_cierre(self):
self._cierre["text"] = "Loading..."
self._cierre["state"] = tk.DISABLED
# TODO: magic
time.sleep(2)
self._cierre["text"] = "foo"
self._cierre["state"] = tk.NORMAL
root = tk.Tk()
root.geometry("240x180")
root.resizable(False, False)
app = Application(root)
root.mainloop()
How do I make the button show text="loading"
and state=DISABLED
, while the button is doing my calculations?
Upvotes: 1
Views: 273
Reputation: 815
There is a pretty quick fix to this problem, you just need to update the button, once you change it's text to "Loading" (self._cierre["text"] = "Loading..."
)
def re_imprimir_ultimo_cierre(self):
self._cierre["text"] = "Loading..."
self._cierre["state"] = tk.DISABLED
self._cierre.update() # This is the line I added
# TODO: magic
time.sleep(2)
self._cierre["text"] = "foo"
self._cierre["state"] = tk.NORMAL
This just simply updates the buttons state after you change the text and state.
From what I understand this is because a button will run all the code within its command, before updating anything on the screen, so you essentially have to force the button to update itself within its command.
Hope this helps :)
Upvotes: 1