Tkinter event_generate command ignored

I am trying to figure out how to remove a binding command in a dialog box. I am trying to do this with tkinter event_generate . This does not work as I expect. For this StackOverflow question, I installed the code with one call to event_generate . Sometimes this line works, and sometimes it looks as if the line does not even exist.

The binding in the __init__ dialog method is as follows:

  self.bind('<BackSpace>', #Print "BackSpace event generated." lambda event: print(event.keysym, 'event generated.')) 

Any action in the dialog box will call back to its completion method (the dialog is based on the example of Frederic Lund in the Introduction to Tkinter.)

  def terminate(self, event=None): print('terminate called') # Make sure we got here and the next line will be called self.event_generate('<BackSpace>') self.parent.focus_set() self.destroy() 

When a dialog is invoked using the code below, any user action ends with a terminate call. In each case, a “call termination” and a “BackSpace event” are generated. are displayed. This proves that the event_generate call is configured correctly.

 parent = tk.Tk() dialog = Dialog(parent) dialog.wait_window() 

In case that matters, I should mention that I switched the Lundh call to self.wait_window from its __init__ dialog method for the caller. Although this violates the neat encapsulation of his dialogue, it seems necessary for automatic unittests. Otherwise, unittest displays a dialog box and stops waiting for user input. I do not like this solution, but I do not know an alternative.

The problem I am facing is when wait_window is replaced by a direct call to the terminate method. This is what I would expect to do in unittesting, which should test my GUI without running tkinter mainloop or wait_window.

 parent = tk.Tk() dialog = Dialog(parent) dialog.terminate() 

It only prints "terminate called" and does not print the "BackSpace event generated". Calling event_generate has no effect. If I follow the call in the debugger, I see that tkinter event_generate() is called with the correct arguments. self = {Dialog} .99999999, sequence = {str}'<BackSpace>', kw = {dict}{} Due to a warning in the TkCmd man pages about window focus, I checked the dialog with binding focused in my __init__ method.

Tkinter does not call back. Why?

EDIT: This bone code with bones shows update . However, it only works if it is called in __init__ before event_generate is called by the main program. (This puzzle was raised as a separate issue )

 class UpdWin(tk.Tk): def __init__(self): super().__init__() self.bind('<BackSpace>', lambda event: print(event.keysym, 'event generated.')) self.update() # Update works if placed here app = UpdWin() app.event_generate('<BackSpace>') # app.update() # Update doesn't work if placed here 
+7
source share
2 answers

event_generate will immediately handle all event event_generate by default. However, if you do not call update before event_generate , the window will not be visible, and tkinter will most likely ignore any events. You can control the processing of the generated event using the when attribute. By default, the value is “now”, but the other option is “tail”, which means adding it to the event queue after processing any events (for example, redraws).

The full documentation on the when attribute is on the tcl / tk man page for event_generate : http://tcl.tk/man/tcl8.5/TkCmd/event.htm#M34

+6
source

I don't know if this applies to your problem, but I got widget.event_generate() to work by first calling widget.focus_set() .

0
source

Source: https://habr.com/ru/post/979978/


All Articles