.place_forget() не выполняется до завершения всего остального в функции

#python #tkinter #time #widget

#python #tkinter #время #виджет

Вопрос:

Итак, у меня есть приведенная ниже функция, которая должна забыть кнопку, повторить счет, подождать одну секунду и вернуть кнопку обратно.

 def iteration():
    global score
    #should hide button
    b1.place_forget()
    #raise score
    score  = 1
    label.config(text = score)
    #wait one second
    sleep(1)
    #bring button back
    b1.place(relx = 0.3, y = 30)
  

Вместо этого place_forget() не запускается до завершения всего остального, в результате чего кнопка никогда не мигает и ждет секунду, прежде чем повторить результат. Почему все происходит в таком порядке и как я могу это исправить? Вот остальная часть моего кода:

 from tkinter import *
from time import sleep

global score
score = 0

def iteration():
    global score
    #should hide button
    b1.place_forget()
    #raise score
    score  = 1
    label.config(text = score)
    #wait one second
    sleep(1)
    #bring button back
    b1.place(relx = 0.3, y = 30)
    
 
root = Tk()  
root.geometry("150x100") 


#make label
label = Label(root, text = score) 
  
# place in the window 
label.place(relx=0.4, y=5) 
  
#make and place button 1
b1 = Button(root, text = "hide text", 
            command = lambda: iteration())
  
b1.place(relx = 0.3, y = 30) 
  
# make and place button 2
b2 = Button(root, text = "retrieve text", 
            command = lambda: iteration())
  
b2.place(relx = 0.3, y = 50) 
  
# Start the GUI 
root.mainloop()
  

Комментарии:

1. В вашем случае вам нужно вызвать root.update() before sleep(1) , чтобы заставить tkinter обновить окно.

2. Был бы признателен за пометку ответа как правильного

Ответ №1:

Я думаю, что процесс происходит, но ваш sleep(1) графический интерфейс зависает, и, следовательно, вы его не видите.

  1. Либо замените sleep(1) , а затем поместите виджет на after() , может получить желаемый эффект, например:
 def iteration():
    global score
    #should hide button
    b1.place_forget()
    #raise score
    score  = 1
    label.config(text = score)
    #wait one second and bring button back
    root.after(1000,lambda: b1.place(relx = 0.3, y = 30))
  

after() предотвращает задержку графического интерфейса на одну секунду там, где он должен скрываться и отображаться.

  1. Или же используйте threading , как:
 import threading
.... #same old codes

b1 = Button(root, text = "hide text",command =lambda: threading.Thread(target=iteration).start())
  

Теперь sleep(1) это не приводит к задержке графического интерфейса, поскольку его нет в потоке tkinter.

  1. Или же вы можете заставить его работать, update() но графический интерфейс по-прежнему может быть заморожен, но он обновляется, кнопка «мигает», например:
 root.update()
sleep(1)
#bring button back
b1.place(relx = 0.3, y = 30)