1

Why does in the code below button1 hang until the time.sleep(10) has completed.

I can only assume tKinter is waiting for the click event to finish before updating it's paint function.

I want on button1 click the state to change to DISABLED as in the code straight away, not when mainformbutton1press() has finished.

I have put time.sleep(10) to mimic rest of code functions - but the actual programme will be many minutes instead.

EDIT! - sleep is just there to show how tkinter hangs. My real programme has lots more code and no sleep function - and it takes a long time to process data with the hung GUI as mentioned. No more sleep suggestions please :)

import tkinter as tk
from tkinter import ttk
from tkinter.constants import DISABLED, NORMAL
import time

# ==================================================
class App:

    def __init__(self, tk, my_w):
  
        self.button1 = tk.Button(my_w, text="START", width=34, command = self.mainformbutton1press)
        self.button1.grid(columnspan=3, row=6, column=1,padx=10,pady=20, ipadx=20, ipady=20)        

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    def mainformbutton1press(self):
  
        self.button1.config(text="PLEASE WAIT...")
        self.button1['state'] = DISABLED
     
        # DO REST OF PROCESSING
        # TO MIMIC THIS:
        time.sleep(10)
        print("doing...")
     
# ==================================================
if __name__ == "__main__":
   
    my_w = tk.Tk()
    my_w.geometry("430x380")
    my_w.resizable(False, False)
    
    app = App(tk, my_w)

    my_w.mainloop()  # Keep the window open
Sylv99
  • 151
  • 8
  • 1
    ```.mainloop``` is a sort of while loop. ```time.sleep()``` stops the loop –  Aug 23 '21 at 09:07
  • Use the ```.after``` scripts –  Aug 23 '21 at 09:07
  • All tkinter update/events are handled by the tkinter `mainloop()`. When `mainformbutton1press()` is being executed, tkinter `mainloop()` does not take the control and so it cannot process the update until the function returns the control. – acw1668 Aug 23 '21 at 09:14
  • Does this answer your question? [Python Tkinter sleep/after not working as expected](https://stackoverflow.com/questions/58376456/python-tkinter-sleep-after-not-working-as-expected) – quamrana Aug 23 '21 at 09:17
  • You've set `sleep` for a 10 second delay. Try reducing it to 1 second. – Derek Aug 23 '21 at 09:18
  • Also insert `self.button1.update()` immediately after button `DISABLED`. – Derek Aug 23 '21 at 09:21

2 Answers2

1

Tk.mainloop is a sort of while loop. time.sleep() stops the loop for a particular period of time. That makes the window unresponsive. You might use .after function:

class App:

    def __init__(self, tk, my_w):
        self.my_w=my_w
        ....
    def continue_next(self):
        print("Doing")
        ....
    def mainformbutton1press(self):
  
        self.button1.config(text="PLEASE WAIT...")
        self.button1['state'] = DISABLED
     
        # DO REST OF PROCESSING
        # TO MIMIC THIS:
        self.my_w.after(10000,self.continue_next)
0

The only change you need to make to your code is to insert an update to your button.

The 10 second delay might need to be shortened (10 seconds is a long time to wait)

self.button1.config(text="PLEASE WAIT...")
self.button1['state'] = DISABLED

# INSERT UPDATE HERE
self.button1.update()
     
# DO REST OF PROCESSING
# TO MIMIC THIS:
time.sleep(1)
print("doing...")
Derek
  • 1,916
  • 2
  • 5
  • 15
  • It's still not a good idea to have `time.sleep` inside `tkinter`. It will make the GUI look choppy even with the `.update()` – TheLizzard Aug 23 '21 at 09:29
  • Sleep is there just to mimic some processing delay, nothing more. – Derek Aug 23 '21 at 09:34
  • Same idea. Even if you have something that is processing for 1 sec, every time the function is called, it might make the GUI choppy. – TheLizzard Aug 23 '21 at 09:35
  • I agree, but sleep is there to **represent** a processing delay. So naturally one would expect it to be removed now that OP's problem has been solved. – Derek Aug 23 '21 at 09:37
  • Even if it's there to *represent processing delay*, it doesn't matter. All that matters is that the GUI will not be updated in that one second. So your answer which is basically: shorten the time taken for the processing/sleeping to around 1 second, will make the GUI choppy. – TheLizzard Aug 23 '21 at 09:44