Python tkinter:在文本小部件标签中停止事件传播

pho*_*bos 6 python tkinter event-handling

我正在写一个配色方案编辑器.对于方案的预览,我使用文本小部件,其中我插入带有相应颜色标签的文本(我以编程方式生成).

我想要的是以下行为:

  • 单击文本小部件上没有文本的任何位置:更改背景颜色
  • 单击插入标签的文本:更改标签对应的前景色

现在这是我的问题:

当我单击标记文本时,将调用标记的回调.到现在为止还挺好.但是,也调用了文本小部件的回调,尽管我在标签回调方法中返回"break"(应该停止进一步的事件处理).我怎么能阻止这个?

为了说明这个具体问题,我写了这个工作示例(对于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()
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏!

编辑:尝试Python 2.

pho*_*bos 2

好吧,在tkint稍微修改了一下之后,我找到了一个可行的解决方案。我认为问题在于标签可能不是 BaseWidget 的子类。

我的解决方法:

  • 对标签进行单独的回调;在那里设置一个变量来跟踪单击了哪个标签
  • 让文本小部件的事件处理程序根据此变量的内容决定要做什么

代码中的解决方法(很抱歉global在这里使用,但我只是修改了我的问题简单示例......):

#!/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()
Run Code Online (Sandbox Code Playgroud)

我希望这对遇到同样问题的人有帮助。

当然,我仍然愿意接受更好的解决方案!