Reputation: 31
I am trying to flash an image using pack() and pack_forget().
We are building a custom BMW, and the lights are run with Raspberry Pi. I have the LED blinkers working using gpiozero, but now I need to show it on a display on the dash. I am able to hide and show the image using Label.pack_forget() and Label.pack() respectively in a function, but I cant get it to flash. I have tried the following code.
This works:
def showBG():
background_label.pack()
def hideBG():
background_label.pack_forget()
hideBttn = tk.Button(window, text="Hide Arrow", command = hideBG)
showBttn = tk.Button(window, text="Show Arrow", command = showBG)
This does not:
import tkinter as tk
from time import sleep
def flashBG():
for i in range(0, 3):
background_label.pack()
sleep(.7)
background_label.pack_forget()
sleep(.3)
showHideBttn = tk.Button(window, text = "Flash Arrow", command = flashBG)
The first example shows and hides the Arrow as expected: Press the Hide Button and it disappears, press the Show Button and it appears.
The second example is supposed to flash 3 times like the blinker in your car on the dash. ON wait .7 secs, OFF wait .3 secs X3...
No errors, I click the Show Hide Button and the Arrow simply disappears when the for loop terminates.
Upvotes: 1
Views: 1809
Reputation: 46678
You should not use pack()
and pack_forget()
to simulate flashing because the label may not be put in the same location if there are more than one widget in the same container.
Also, using sleep()
will block the mainloop()
from processing pending events which causes the background_label
not being updated.
You should change the foreground color of the label to simulate flashing:
First save the foreground and background colors of the label after it is created:
flash_colors = (background_label.cget('bg'), background_label.cget('fg'))
# then flash_colors[0] is label background color
# and flash_colors[1] is label foreground color
Then modify flashBG()
as below:
def flashBG(count=0, color_idx=0):
# set label text color to background color (color_idx=0) to hide the label
# or to foreground color (color_idx=1) to show the label
background_label.config(fg=flash_colors[color_idx])
if count < 5:
# execute flashBG() again after 300ms or 700ms based on the color of the label
window.after(300 if color_idx==0 else 700, flashBG, count+1, 1-color_idx)
flashBG(...)
will be executed 6 times (OFF 3 times, ON 3 times).
Upvotes: 4
Reputation: 2161
see How to make a flashing text box in tkinter?
The for loop will execute in its entirety before the effect is made on the tkinter widget. Since the last thing it does is pack_forget(), nothing appears
Upvotes: 1