【问题标题】:How do I bind the enter key to a function in tkinter?如何将回车键绑定到 tkinter 中的函数?
【发布时间】:2013-06-04 11:43:31
【问题描述】:

我是一名 Python 初学者,在 MacOS 上运行。

我正在 tkinter 中制作一个带有文本解析器 GUI 的程序,您在 Entry 小部件中键入命令,然后点击 Button 小部件,这会触发我的 parse() 函数等,打印结果到 Text 小部件,文本冒险风格。

>绕过按钮

我不能让你那样做,戴夫。

我正试图找到一种方法来摆脱每次用户发出命令时将鼠标拖到Button 的需要,但这比我想象的要难。

我猜正确的代码看起来像self.bind('<Return>', self.parse())?但我什至不知道该放在哪里。 root__init__parse()create_widgets() 不想要。

需要明确的是,任何人都应该在 prog 中按 enter 的唯一原因是触发 parse(),因此不需要专门支持 Entry 小部件。它在任何地方都可以正常工作。

响应7stud,基本格式:

from tkinter import *
import tkinter.font, random, re

class Application(Frame):
    
    def __init__(self, master):
        Frame.__init__(self, master, ...)
        self.grid()
        self.create_widgets()
        self.start()

        
    def parse(self):
        ...


    def create_widgets(self):
        
        ...

        self.submit = Button(self, text= "Submit Command.", command= self.parse, ...)
        self.submit.grid(...)

        
root = Tk()
root.bind('<Return>', self.parse)

app = Application(root)

root.mainloop()

【问题讨论】:

    标签: python python-3.x tkinter key-bindings


    【解决方案1】:

    尝试运行以下程序。你只需要确保你的窗口在你点击 Return 时获得焦点——为了确保它确实如此,首先点击按钮几次直到你看到一些输出,然后不点击其他任何地方点击 Return。

    import tkinter as tk
    
    root = tk.Tk()
    root.geometry("300x200")
    
    def func(event):
        print("You hit return.")
    root.bind('<Return>', func)
    
    def onclick():
        print("You clicked the button")
    
    button = tk.Button(root, text="click me", command=onclick)
    button.pack()
    
    root.mainloop()
    

    然后,当让button clickhitting Return 调用同一个函数时,您只需稍作调整——因为命令函数需要是不带参数的函数,而绑定函数需要是接受一个参数的函数(事件对象):

    import tkinter as tk
    
    root = tk.Tk()
    root.geometry("300x200")
    
    def func(event):
        print("You hit return.")
    
    def onclick(event=None):
        print("You clicked the button")
    
    root.bind('<Return>', onclick)
    
    button = tk.Button(root, text="click me", command=onclick)
    button.pack()
    
    root.mainloop()
    

    或者,您可以放弃使用按钮的命令参数,而是使用 bind() 将 onclick 函数附加到按钮,这意味着该函数需要一个参数——就像使用 Return 一样:

    import tkinter as tk
    
    root = tk.Tk()
    root.geometry("300x200")
    
    def func(event):
        print("You hit return.")
    
    def onclick(event):
        print("You clicked the button")
    
    root.bind('<Return>', onclick)
    
    button = tk.Button(root, text="click me")
    button.bind('<Button-1>', onclick)
    button.pack()
    
    root.mainloop()
    

    这是在班级设置中:

    import tkinter as tk
    
    class Application(tk.Frame):
        def __init__(self):
            self.root = tk.Tk()
            self.root.geometry("300x200")
    
            tk.Frame.__init__(self, self.root)
            self.create_widgets()
    
        def create_widgets(self):
            self.root.bind('<Return>', self.parse)
            self.grid()
    
            self.submit = tk.Button(self, text="Submit")
            self.submit.bind('<Button-1>', self.parse)
            self.submit.grid()
    
        def parse(self, event):
            print("You clicked?")
    
        def start(self):
            self.root.mainloop()
    
    
    Application().start()
    

    【讨论】:

    • @Ghosty,我又添加了两个例子。
    • 你显然在你的程序中使用类,所以如果你只发布你的类的基本结构(它们可以是空的),我可以修改示例让你在类设置中工作。
    • @Ghosty,我在课堂设置中发布了一个示例。请务必记住,如果您使用 command 参数将处理程序函数附加到按钮,则该函数不能接受任何参数。另一方面,如果您使用 bind() 附加处理函数,则该函数必须接受一个参数。查看我发布的示例,了解如何处理。
    • 这里是一些在 tkinter 中处理事件的文档。 python-course.eu/tkinter_events_binds.php
    【解决方案2】:

    另一种选择是使用 lambda:

    ent.bind("<Return>", (lambda event: name_of_function()))
    

    完整代码:

    from tkinter import *
    from tkinter.messagebox import showinfo
    
    def reply(name):
        showinfo(title="Reply", message = "Hello %s!" % name)
    
    
    top = Tk()
    top.title("Echo")
    top.iconbitmap("Iconshock-Folder-Gallery.ico")
    
    Label(top, text="Enter your name:").pack(side=TOP)
    ent = Entry(top)
    ent.bind("<Return>", (lambda event: reply(ent.get())))
    ent.pack(side=TOP)
    btn = Button(top,text="Submit", command=(lambda: reply(ent.get())))
    btn.pack(side=LEFT)
    
    top.mainloop()
    

    如您所见,使用未使用的变量“event”创建 lambda 函数可以解决问题。

    【讨论】:

    • 您的代码引用了本地图像Iconshock-Folder-Gallery.ico其他用户无权访问。
    【解决方案3】:

    我发现使用绑定的一个好处是您可以了解触发事件:类似于:“您点击了事件 = [ButtonPress event state=Mod1 num=1 x=43 y=20]”,因为代码如下:

    self.submit.bind('<Button-1>', self.parse)
    def parse(self, trigger_event):
            print("You clicked with event = {}".format(trigger_event))
    

    比较以下两种编码按钮单击的方式:

    btn = Button(root, text="Click me to submit", command=(lambda: reply(ent.get())))
    btn = Button(root, text="Click me to submit")
    btn.bind('<Button-1>', (lambda event: reply(ent.get(), e=event)))
    def reply(name, e = None):
        messagebox.showinfo(title="Reply", message = "Hello {0}!\nevent = {1}".format(name, e))
    

    第一个是使用不带参数的命令函数,因此不可能传入事件。 第二个是绑定函数,它可以接受事件传入并打印类似“Hello Charles!event = [ButtonPress event state=Mod1 num=1 x=68 y=12]”的内容

    我们可以左键单击、中键单击或右键单击鼠标,分别对应事件编号 1、2 和 3。代码:

    btn = Button(root, text="Click me to submit")
    buttonClicks = ["<Button-1>", "<Button-2>", "<Button-3>"]
    for bc in buttonClicks:
        btn.bind(bc, lambda e : print("Button clicked with event = {}".format(e.num)))
    

    输出:

    Button clicked with event = 1
    Button clicked with event = 2
    Button clicked with event = 3
    

    【讨论】:

      猜你喜欢
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 2012-10-30
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      相关资源
      最近更新 更多