I have access to the top level tkinter window, but when I do:
self._root = tk.Tk()
<snip>
x = 10 # in screen coordinates
y = 20 # in screen coordinates
self._root.event_generate('<Button-1>', x=x, y=y)
self._root.event_generate('<ButtonRelease-1>', x=x, y=y)
I expect the button click to be applied to the widget underneath location x,y on the window. In this example a Button.
My understanding is event_generate places an event on the message queue inside tkinter just like a real mouse click would do. Normally clicking anywhere inside a window or a frame, causes the click to go through the top-level panes until it finds a widget with a bind() associated with it, i.e. a Button.
And so using that I should be able to simulate a button click anywhere on the window without moving the actual mouse.
But it doesn't do anything, no click, no error, no anything.
What am I missing?
CodePudding user response:
event_generate
is not the same as simulating a click by the user. Instead, you're explicitly specifying the window that is to receive the event.
If you need to simulate the actions of a user, you can use the method winfo_containing
which will return the widget at a given coordinate. You can then pass that widget to event_generate
.
CodePudding user response:
With @Bryan Oakley's excellent help, I was able to get this to work:
# the top level window
self._root = tk.Tk()
<snip>
x = 10 # in screen coordinates
y = 20 # in screen coordinates
# get a reference to the widget in the root window that is
# underneath coordinate x,y
w = self._root.winfo_containing(x, y)
# Note: the <Enter> is necessary. Without it the
# button events don't do anything.
w.event_generate('<Enter>', x=x, y=y)
w.event_generate('<Button-1>', x=x, y=y)
w.event_generate('<ButtonRelease-1>', x=x, y=y)
# The invoke() also works.
# w.invoke()
Note: the widget in this sample is a Button. I have not yet tried this same technique on other widgets e.g. an Entry or RadioButton widget. There may need to be additional event_generate() calls or additional events to make that work.