提问人:Quinten 提问时间:10/16/2023 最后编辑:toyota SupraQuinten 更新时间:10/16/2023 访问量:50
特金特。如何将 bind_class 方法用于多个条目小部件
Tkinter. How can one use the bind_class method for multiple entry widgets
问:
我想知道是否有人可以帮忙。 我有一个带有多个条目小部件的框架。当读取文件时,它们会填充数据。 现在我想单击其中一个并通过按 F8 键清除文本。 我可以做这个长手并将 F8 键绑定到每个小部件,但我可以使用 bind_class 或 bind_all 方法来执行此操作吗?
我在下面微弱的尝试:
import tkinter
import tkinter as ttk
# from ttkthemes import ThemedTk
class Frame1(ttk.Frame):
def __init__(self, master):
super().__init__(master)
self.bind_class('Entry', '<F8>', self.clearfield)
self.label = ttk.Label(self, text="Name")
self.label2 = ttk.Label(self, text="Contact")
self.name = ttk.Entry(self, width = 30, text="")
self.contact = ttk.Entry(self, width = 20, text="")
self.label.grid(row=1, column=0, padx=10, pady=5, sticky="w")
self.label2.grid(row=2, column=0, padx=10, pady=5, sticky="w")
self.name.grid(row=1, column=1, padx=10, pady=5, sticky="w")
self.contact.grid(row=2, column=1, padx=10, pady=5, sticky="w")
def clearfield(self, event):
insert = self.ttk.Entry.index("insert")
self.ttk.Entry.delete(0, insert)
class App(tkinter.Tk):
def __init__(self):
super().__init__()
# style = ttk.Style(self)
# style.theme_use("alt")
self.title("Test")
self.geometry("250x300")
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.bind_class('Entry', '<F8>', self.clearfield)
self.acc_no = ttk.Entry(self, width = 60, text="Acc. no.")
self.acc_no.grid(row=0, column=0, padx=10, pady=10, sticky="w")
self.acc_no.focus_set()
self.frame1 = Frame1(self)
self.frame1.grid(row=1, column=0, padx=10, pady=(10, 10), sticky="nsw")
def clearfield(self, event):
insert = self.acc_no.index("insert")
self.acc_no.delete(0, insert)
app=App()
app.mainloop()
互联网上没有任何内容可以解释这一点,我尝试了各种选择,但没有成功。
答:
0赞
Bryan Oakley
10/16/2023
#1
您唯一的错误是尝试在回调中使用。调用绑定回调时,会传递一个对象。该对象具有一个名为的属性,该属性告诉您哪个小部件接收了事件。self
event
widget
以下示例说明了这一点。它还删除了计算索引的不必要步骤,而是使用符号索引。"insert"
def clearfield(self, event):
event.widget.delete(0, "insert")
如果要删除所有插入点之前的所有内容,而不是仅删除插入点之前的所有内容,请使用 代替 ."end"
"insert"
def clearfield(self, event):
event.widget.delete(0, "end")
评论
0赞
Quinten
10/16/2023
非常感谢您的帮助,它现在可以工作:)
0赞
acw1668
10/16/2023
#2
由于您已经调用了两次(一个在内部,一个在内部),因此后者将覆盖前者,即即使您按下内部也会执行。bind_class("Entry", ...)
App.__init__()
Frame1.__init__()
Frame1.clearfield()
<F8>
self.acc_no
此外,里面的代码也无法正常工作,如评论中所述。Frame1.clearfield()
我建议创建一个实现绑定的自定义小部件,并使用此自定义小部件,而不是当您想要拥有此类功能时:ttk.Entry
ttk.Entry
import tkinter
import tkinter as ttk
# custom class to have the required event binding
class MyEntry(ttk.Entry):
def __init__(self, master=None, **kwargs):
super().__init__(master, **kwargs)
self.bind("<F8>", lambda e: e.widget.delete(0, "insert"))
class Frame1(ttk.Frame):
def __init__(self, master):
super().__init__(master)
self.label = ttk.Label(self, text="Name")
self.label2 = ttk.Label(self, text="Contact")
# use the custom Entry class
self.name = MyEntry(self, width = 30, text="")
self.contact = MyEntry(self, width = 20, text="")
self.label.grid(row=1, column=0, padx=10, pady=5, sticky="w")
self.label2.grid(row=2, column=0, padx=10, pady=5, sticky="w")
self.name.grid(row=1, column=1, padx=10, pady=5, sticky="w")
self.contact.grid(row=2, column=1, padx=10, pady=5, sticky="w")
class App(tkinter.Tk):
def __init__(self):
super().__init__()
self.title("Test")
self.geometry("250x300")
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
# use the custom Entry class
self.acc_no = MyEntry(self, width = 60, text="Acc. no.")
self.acc_no.grid(row=0, column=0, padx=10, pady=10, sticky="w")
self.acc_no.focus_set()
self.frame1 = Frame1(self)
self.frame1.grid(row=1, column=0, padx=10, pady=(10, 10), sticky="nsw")
app=App()
app.mainloop()
评论
0赞
Quinten
10/16/2023
哇,好吧,没想到。
0赞
Quinten
10/16/2023
非常感谢您的帮助,它有效。
评论
F8
F5
insert = self.ttk.Entry.index("insert")
event.widget
self.ttk.Entry
F8
event.widget.delete(0, "insert")