特金特。如何将 bind_class 方法用于多个条目小部件

Tkinter. How can one use the bind_class method for multiple entry widgets

提问人:Quinten 提问时间:10/16/2023 最后编辑:toyota SupraQuinten 更新时间:10/16/2023 访问量:50

问:

我想知道是否有人可以帮忙。 我有一个带有多个条目小部件的框架。当读取文件时,它们会填充数据。 现在我想单击其中一个并通过按 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()

互联网上没有任何内容可以解释这一点,我尝试了各种选择,但没有成功。

python-3.x tkinter 小部件 绑定按

评论

0赞 TheLizzard 10/16/2023
我被我的操作系统绑定了。当我将其更改为 时,它会在 上引发错误。我猜你想要而不是.当您按下系统时会发生什么?此外,您可以使用 .F8F5insert = self.ttk.Entry.index("insert")event.widgetself.ttk.EntryF8event.widget.delete(0, "insert")

答:

0赞 Bryan Oakley 10/16/2023 #1

您唯一的错误是尝试在回调中使用。调用绑定回调时,会传递一个对象。该对象具有一个名为的属性,该属性告诉您哪个小部件接收了事件。selfeventwidget

以下示例说明了这一点。它还删除了计算索引的不必要步骤,而是使用符号索引。"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.Entryttk.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
非常感谢您的帮助,它有效。