I am trying to get tkinter event_generate
to work with update
for atomic unittesting.
The following code does not work as I expect. "BackSpace event generated." not printed. I understand that event_generate
puts the event in the tkinter event queue, and then update
should clear and execute all the events in the queue.
class UpdWin(tk.Tk): def __init__(self): super().__init__() self.bind('<BackSpace>', lambda event: print(event.keysym, 'event generated.')) app = UpdWin() app.event_generate('<BackSpace>') app.update()
However, the following code prints the "BackSpace" event. Events in the event queue are cleared and executed during __init__
. After that, the main code places the event in the tkinter queue.
class UpdWin(tk.Tk): def __init__(self): super().__init__() self.bind('<BackSpace>', lambda event: print(event.keysym, 'event generated.')) self.update()
My first thought was that my understanding of the update
command should have been wrong. Lundh, Shipman and TclCmd pages have different entries for update
.
Process all pending events, call event callbacks, complete any pending geometry control, redraw widgets if necessary, and call all pending inactivity tasks. Lundh (1999)
This method forces the display to be updated. Shipman (New Mexico Tech)
This command is used to bring the application to the "actual" state by entering the event loop several times until all pending events (including callbacks) are processed. TclCmd man page
From this, I suspected an undocumented time issue, and I tried third place for the update team. The following code also works.
class UpdWin(tk.Tk): def __init__(self): super().__init__() self.bind('<BackSpace>', lambda event: print(event.keysym, 'event generated.')) app = UpdWin() app.update()
Why does tkinter update
work when it called before event_generate
, but not after?
Edit
The following code will print the message "BackSpace event generated". if app.update
is in position 1.
He will print a "FocusIn event." if app.update
is in position 2.
NB: Brian Oakley's answer says this effect may be machine dependent.
import tkinter as tk app = tk.Tk() # app.update() # Position 1 app.bind('<FocusIn>', lambda event: print('FocusIn event generated.')) app.bind('<BackSpace>', lambda event: print(event.keysym, 'event generated.')) app.event_generate('<BackSpace>') app.update() # Position 2
The following code using when='tail'
never prints a "BackSpace event". whether app.update
in position 1 or 2.
import tkinter as tk app = tk.Tk() app.update() # Position 1 app.bind('<FocusIn>', lambda event: print('<FocusIn> event generated.')) app.bind('<BackSpace>', lambda event: print(event.keysym, 'event generated.')) app.event_generate('<BackSpace>', when="tail") # app.update() # Position 2