将<Return>绑定到按钮上未按预期工作

6

我将事件<Return>绑定到一个按钮上,认为这样会在按下Enter键后运行command

Button(self.f, text="Print", command=self.Printer).pack(side=RIGHT, padx=10, pady=10)
self.button1 = Button(self.f, text="search", command=self.search)
self.button1.bind('<Return>', self.search)
self.button1.pack(side=RIGHT, padx=10, pady=10)

但是它什么也没做。当按下 Enter 键时,我该怎么做才能运行 self.search

1个回答

13

你的代码看起来没问题,但需要注意,如果你想通过按下 Return 键来调用 self.search() 函数,则焦点必须在按钮上。您可以通过按下 Tab 键将焦点从小部件切换到另一个小部件。当前焦点的小部件会被细黑线框出。在按下 Return 按键之前,您可能需要按一次或多次 Tab 键以将焦点移动到按钮上。

如果你希望在GUI窗口的任何位置都能使用 Return 键,则更改

self.button1.bind('<Return>', self.search)

转化为

root.bind('<Return>', self.search)

其中 root = tk.Tk()

例如,将下面代码中的 button.bindmaster.bind 进行比较:

import Tkinter as tk

class SimpleApp(object):
    def __init__(self, master, **kwargs):
        title = kwargs.pop('title')
        frame = tk.Frame(master, **kwargs)
        frame.grid()
        button = tk.Button(frame, text = 'search', command = self.search)
        button.grid()
        button.bind('<Return>', self.search)
        # uncomment if you want `<Return>` bound everywhere.
        # master.bind('<Return>', self.search)  
    def search(self,*args):
        print('searching...')

def basic():
    root = tk.Tk()
    app = SimpleApp(root, title = 'Hello, world')
    root.mainloop()

basic()

或者,您也可以使用


    button.bind('<Return>', self.search)
    button.focus()

这种方法的作用是,只有当按钮具有焦点时才会调用 self.search(),而应用程序开始时按钮就获取了焦点。


关于使用 *args**kwargs

**kwargs 允许传递任意关键字参数到 __init__

当像这样在函数定义中使用 **kwargs

def __init__(self, master, **kwargs):

我们可以这样实例化SimpleApp:

app = SimpleApp(root, title = 'Hello, world')

然后Python将kwargs设置为一个包含关键字参数的字典,例如:{'title':'Hello, world'}。请注意,**kwargs是Python语法,只能用于函数定义和函数调用(见下文),但kwargs本身只是一个字典。

kwargs然后传递给Frame

frame = tk.Frame(master, **kwargs)

现在,在函数调用中使用 **kwargs 时,kwargs 字典中的键值对会被展开,因此上面的函数调用等同于:

frame = tk.Frame(master, title = 'Hello, world')
由于 Frame 可以接受多种关键字参数,而我不知道它们全部是什么,也不想枚举它们,因此使用 **kwargs 是有优势的。请注意,即使在以后的某个时候向 Frame 添加了新的关键字参数,我的代码仍将正常工作,而如果我明确拼出关键字,则我的代码将无法自动“升级”,如果 Frame 的可允许关键字发生更改。

类似地,*args 允许您将任意位置参数包含到 search 中:

def search(self,*args):

Python将args设置为包含调用search时发送的所有位置参数的列表。

我在这里使用了*args,因为调用self.search时没有参数或一个参数。

当你说

button = tk.Button(frame, text = 'search', command = self.search)

当单击按钮时,self.search()将不带参数调用。但是当你说

    button.bind('<Return>', self.search)

当按下"Return"键时,self.search(event)会带有一个参数进行调用。其中event是一个Tkinter.Event对象,它具有一些属性(如:time, state, type, widget, x, y等),这些属性可以让你更多地了解发生的事件。

另一种也许更好的定义search的方式是:

def search(self, event = None):
    ...

这将表明search可能接收0个或1个参数,而不仅仅是任意数量的参数。如果传递了事件给search,这也将更容易访问event

参考:


谢谢,现在我更清楚了。只是想问一下,这些 "**kwargs" 和 "*args" 是什么意思? - Thomas
我添加了为什么使用 **kwargs*args 的解释。如果太长不想读,可以参考 saltcrane 的解释 - unutbu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接