Tkinter ttk Treeview binding responds to past events!

MRAB python at mrabarnett.plus.com
Tue Sep 12 20:33:27 EDT 2023


On 2023-09-13 00:40, John O'Hagan via Python-list wrote:
> On Tue, 2023-09-12 at 20:51 +0200, Mirko via Python-list wrote:
>> Am 12.09.23 um 07:43 schrieb John O'Hagan via Python-list:
>> 
>> > My issue is solved, but I'm still curious about what is happening
>> > here.
>> 
>> MRAB already said it: When you enter the callback function, Tk's 
>> mainloop waits for it to return. So what's happening is:
>> 
>> 1. Tk's mainloop pauses
>> 2. temp_unbind() is called
>> 3. TreeviewSelect is unbound
>> 4. events are queued
>> 5. TreeviewSelect is bound again
>> 6. temp_unbind() returns
>> 7. Tk's mainloop continues with the state:
>>  - TreeviewSelect is bound
>>  - events are queued
>> 
>> [. . .]
> 
> Thanks (also to others who have explained), now I get it!
> 
> 
>> FWIW, here's a version without after(), solving this purely on the 
>> python side, not by temporarily unbinding the event, but by 
>> selectively doing nothing in the callback function.
>> 
>> from tkinter import *
>> from tkinter.ttk import *
>> 
>> class Test:
>>      def __init__(self):
>>          self.inhibit = False
>>          root=Tk()
>>          self.tree = Treeview(root)
>>          self.tree.pack()
>>          self.iid = self.tree.insert('', 0, text='test')
>>          Button(root, command=self.temp_inhibit).pack()
>>          mainloop()
>> 
>>      def callback(self, *e):
>>          if not self.inhibit:
>>              print('called')
>> 
>>      def temp_inhibit(self):
>>          self.inhibit = True
>>          self.tree.selection_set(self.iid)
>>          self.tree.selection_remove(self.iid)
>>          self.tree.selection_set(self.iid)
>>          self.inhibit = False
>>          self.callback()
>> 
>> c=Test()
>> 
> 
> 
> I like this solution better - it's much more obvious to me what it's
> doing.
> 
That code is not binding at all, it's just calling 'temp_inhibit' when 
the button is clicked.

You can remove all uses of self.inhibit and rename 'temp_inhibit' to 
something more meaningful, like 'delete_item'.



More information about the Python-list mailing list