Am 11.09.23 um 14:30 schrieb John O'Hagan via Python-list:
I was surprised that the code below prints 'called' three times.
from tkinter import *
from tkinter.ttk import *
root=Tk()
def callback(*e):
print('called')
tree = Treeview(root)
tree.pack()
iid = tree.insert('', 0, text='test')
tree.selection_set(iid)
tree.selection_remove(iid)
tree.selection_set(iid)
tree.bind('<<TreeviewSelect>>', callback)
mainloop()
In other words, selection events that occurred _before_ the callback
function was bound to the Treeview selections are triggering the
function upon binding. AFAIK, no other tk widget/binding combination
behaves this way (although I haven't tried all of them).
This was a problem because I wanted to reset the contents of the
Treeview without triggering a relatively expensive bound function, but
found that temporarily unbinding didn't prevent the calls.
I've worked around this by using a regular button-click binding for
selection instead, but I'm curious if anyone can cast any light on
this.
Cheers
John
AFAIK (it's been quite some time, since I used Tk/Tkinter):
These selection events are not triggered upon binding, but after the
mainloop has startet. Tk's eventloop is queue-driven, so the
tree.selection_{set,remove}() calls just place the events on the
queue. After that, you setup a callback and when the mainloop
starts, it processes the events from the queue, executing the
registered callback.
I seem to remember, that I solved a similar issue by deferring the
callback installation using root.after().
from tkinter import *
from tkinter.ttk import *
root=Tk()
def callback(*e):
print('called')
tree = Treeview(root)
tree.pack()
iid = tree.insert('', 0, text='test')
tree.selection_set(iid)
tree.selection_remove(iid)
tree.selection_set(iid)
root.after(100, lambda: tree.bind('<<TreeviewSelect>>', callback))
mainloop()
This does not print "called" at all after startup (but still selects
the entry), because the callback has not been installed when the
mainloop starts. But any subsequent interaction with the list
(clicking) will print it (since the callback is then setup).
HTH
--
https://mail.python.org/mailman/listinfo/python-list