tkinter: stopping event propagation in text widgets tags
event-handling, python, tkinter
Solution
Okay, after tkint tinkering around a bit, I was able to figure out a working solution. I think the problem is that tags are probably not subclassed from BaseWidget.
My workaround:
- Make a seperate callback for the tags; set a variable there which keeps track of which tag was clicked
- Let the event handler of the text widget decide what to do depending on the content of this variable
The workaround in code (sorry for using `global` here, but I just modified my questions simple example...):
#!/usr/bin/env python
try:
from Tkinter import *
from tkMessageBox import showinfo
except ImportError:
from tkinter import *
from tkinter.messagebox import showinfo
tag_to_handle = ''
def on_click(event, widget_origin='?'):
global tag_to_handle
if tag_to_handle:
showinfo('Click', '"{}" clicked'.format(tag_to_handle))
tag_to_handle = ''
else:
showinfo('Click', '"{} " clicked'.format(widget_origin))
def on_tag_click(event, tag):
global tag_to_handle
tag_to_handle = tag
root = Tk()
text = Text(root)
text.pack()
text.insert(CURRENT, 'Some untagged text...\n')
text.bind('<Button-1>', lambda e, w='textwidget': on_click(e, w))
for i in range(5):
tag_name = 'tag_{}'.format(i)
text.tag_config(tag_name)
text.tag_bind(tag_name, '<Button-1>',
lambda e, w=tag_name: on_tag_click(e, w))
text.insert(CURRENT, tag_name + ' ', tag_name)
root.mainloop()
I hope this is helpful for people having the same problem.
I'm still open to nicer solutions of course!
Problem
I'm currently writing a color scheme editor. For the preview of the scheme, I use a text widget, where I insert text with the corresponding color tags (which I generate programmatically). What I want is the following behaviour: - click anywhere on the text widget where no text is: change background color - click on text inserted with a tag: change tags corresponding foreground color Now here's my problem: When I click on a tagged text, the callback of the tag is called. So far so good. But then, the callback of the text widget is called as well, although I return "break" in the tags callback method (which should stop further event handling). How can I stop this? To illustrate this specific problem, I wrote this working example (for Python 2 & 3): ``` #!/usr/bin/env python try: from Tkinter import * from tkMessageBox import showinfo except ImportError: from tkinter import * from tkinter.messagebox import showinfo def on_click(event, widget_origin='?'): showinfo('Click', '"{}"" clicked'.format(widget_origin)) return 'break' root = Tk() text = Text(root) text.pack() text.insert(CURRENT, 'Some untagged text...\n') text.bind('<Button-1>', lambda e, w='textwidget': on_click(e, w)) for i in range(5): tag_name = 'tag_{}'.format(i) text.tag_config(tag_name) text.tag_bind(tag_name, '<Button-1>', lambda e, w=tag_name: on_click(e, w)) text.insert(CURRENT, tag_name + ' ', tag_name) root.mainloop() ``` Any help is appreciated! Edit: Tried Python 2 as well.