Python tkinter 覆盖默认的 ctrl-h 绑定
Python tkinter override default ctrl-h binding
绑定 ctrl-h 没问题。但是,当我执行 ctrl-h 时,我注意到最后一个字符也从条目中删除了。我认为这可能是 python 的默认 ctrl-h 绑定。我怎样才能禁用它?
---更新---
我添加了 return 'break'
东西。但它仍然不起作用。在 askstring 对话框出现之前,最后一个字符被立即删除。这是绑定的代码。
def replace(self):
target = simpledialog.askstring(title = 'Replace', prompt = 'Replace Target')
if not target:
return 'break'
withValue = simpledialog.askstring(title = 'Replace', prompt = 'Replace With')
if not withValue:
return 'break'
for entry in self.entries.values():
setEntry(entry, entry.get().replace(target, withValue))
return 'break'
顺便说一句,我绑定的是master而不是条目,因为我有很多条目。绑定master更简单
我是这样绑定的
self.master.bind('<Control-h>', lambda event: self.replace())
self.master
定义在这里:
class Generator(Frame):
def __init__(self, master):
Frame.__init__(self, master)
## init variables
self.master = master
这是我传入的
root = Tk()
gui = Generator(root)
gui.pack()
root.title('Generator')
root.mainloop()
因为您绑定到根 window 而不是单个小部件,所以您无法在函数中执行任何操作。绑定按以下顺序处理:
- 特定小部件上的绑定
- 小部件上的绑定 class
- 顶级 window 上的绑定,其中存在小部件
- 特殊标签上的绑定 "all"
如果在处理这些绑定的任何时候一个函数 return 字符串 "break",则不会进行进一步的处理。因此,如果您在特定小部件上有绑定并且 return "break",则不会处理默认的 class 绑定。但是,如果您 return "break" 从绑定到根 window,则在 class 绑定之后才会处理该绑定。因此,这种绑定不可能阻止默认行为。
但是,tkinter 绑定非常可定制,因此有解决方案。鉴于您可能想要抑制默认行为,最直接的解决方案是绑定到 class 以便您完全替换默认行为,或者单独绑定到每个小部件以便您可以防止 class 绑定发生。
如果您真的希望通过绑定到根 window 来实现通用绑定,那么最简单的解决方案可能是更改所有具有 control-h 默认绑定的小部件的处理顺序。
例如,要将根级绑定的处理移到 class 级绑定之前,您可以这样做:
entry = tk.Entry(root)
bindtags = entry.bindtags()
entry.bindtags((bindtags[2], bindtags[0], bindtags[1], bindtags[3]))
有关绑定处理方式的详细信息,您可能需要查看以下问题:
- Basic query regarding bindtags in tkinter
- How to bind self events in Tkinter Text widget after it will binded by Text widget?
这是一个绑定到根 window 的简单示例,但更改了绑定标签,以便可以通过 returning "break":[=14 来破坏默认绑定=]
import tkinter as tk
def custom_backspace(event):
entry.insert("insert", "<backspace>")
return "break"
root = tk.Tk()
entry = tk.Entry(root)
entry.pack(fill="x")
bindtags = entry.bindtags()
entry.bindtags((bindtags[2], bindtags[0], bindtags[1], bindtags[3]))
root.bind("<Control-h>", custom_backspace)
root.mainloop()
绑定 ctrl-h 没问题。但是,当我执行 ctrl-h 时,我注意到最后一个字符也从条目中删除了。我认为这可能是 python 的默认 ctrl-h 绑定。我怎样才能禁用它?
---更新---
我添加了 return 'break'
东西。但它仍然不起作用。在 askstring 对话框出现之前,最后一个字符被立即删除。这是绑定的代码。
def replace(self):
target = simpledialog.askstring(title = 'Replace', prompt = 'Replace Target')
if not target:
return 'break'
withValue = simpledialog.askstring(title = 'Replace', prompt = 'Replace With')
if not withValue:
return 'break'
for entry in self.entries.values():
setEntry(entry, entry.get().replace(target, withValue))
return 'break'
顺便说一句,我绑定的是master而不是条目,因为我有很多条目。绑定master更简单
我是这样绑定的
self.master.bind('<Control-h>', lambda event: self.replace())
self.master
定义在这里:
class Generator(Frame):
def __init__(self, master):
Frame.__init__(self, master)
## init variables
self.master = master
这是我传入的
root = Tk()
gui = Generator(root)
gui.pack()
root.title('Generator')
root.mainloop()
因为您绑定到根 window 而不是单个小部件,所以您无法在函数中执行任何操作。绑定按以下顺序处理:
- 特定小部件上的绑定
- 小部件上的绑定 class
- 顶级 window 上的绑定,其中存在小部件
- 特殊标签上的绑定 "all"
如果在处理这些绑定的任何时候一个函数 return 字符串 "break",则不会进行进一步的处理。因此,如果您在特定小部件上有绑定并且 return "break",则不会处理默认的 class 绑定。但是,如果您 return "break" 从绑定到根 window,则在 class 绑定之后才会处理该绑定。因此,这种绑定不可能阻止默认行为。
但是,tkinter 绑定非常可定制,因此有解决方案。鉴于您可能想要抑制默认行为,最直接的解决方案是绑定到 class 以便您完全替换默认行为,或者单独绑定到每个小部件以便您可以防止 class 绑定发生。
如果您真的希望通过绑定到根 window 来实现通用绑定,那么最简单的解决方案可能是更改所有具有 control-h 默认绑定的小部件的处理顺序。
例如,要将根级绑定的处理移到 class 级绑定之前,您可以这样做:
entry = tk.Entry(root)
bindtags = entry.bindtags()
entry.bindtags((bindtags[2], bindtags[0], bindtags[1], bindtags[3]))
有关绑定处理方式的详细信息,您可能需要查看以下问题:
- Basic query regarding bindtags in tkinter
- How to bind self events in Tkinter Text widget after it will binded by Text widget?
这是一个绑定到根 window 的简单示例,但更改了绑定标签,以便可以通过 returning "break":[=14 来破坏默认绑定=]
import tkinter as tk
def custom_backspace(event):
entry.insert("insert", "<backspace>")
return "break"
root = tk.Tk()
entry = tk.Entry(root)
entry.pack(fill="x")
bindtags = entry.bindtags()
entry.bindtags((bindtags[2], bindtags[0], bindtags[1], bindtags[3]))
root.bind("<Control-h>", custom_backspace)
root.mainloop()