Привязка <Return>к кнопке не работает должным образом - PullRequest
6 голосов
/ 30 декабря 2011

Я связал событие <Return> с кнопкой, думая, что это приведет к запуску command после нажатия Enter :

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)

Но это ничего не делает. Что я должен сделать для запуска self.search при нажатии Enter ?

1 Ответ

13 голосов
/ 30 декабря 2011

Ваш код выглядит нормально, но обратите внимание, что фокус должен быть на кнопке, если вы хотите, чтобы Return позвонил self.search().Вы можете изменить фокус с виджета на виджет, нажав Tab.Виджет в фокусе обведен тонкой черной линией.Возможно, вам придется нажать Tab один или несколько раз, чтобы переместить фокус на кнопку, прежде чем нажимать Return.

Если вы хотите, чтобы Return работал в любом месте окна графического интерфейса, затем измените

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

до

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

, где root = tk.Tk().

Например, сравните button.bind с master.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()

. Делая это таким образом, нажатие Return вызывает 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 dict расширяются, так что приведенный выше вызов функции эквивалентен

frame = tk.Frame(master, title = 'Hello, world')

Поскольку Frame может принимать множество аргументов ключевых слов, и я не знаю их всех и не хочу перечислять их, выгодно использовать **kwargs.Также обратите внимание, что даже если новые аргументы ключевых слов были добавлены в Frame позднее, мой код все равно будет работать, тогда как, если я прописал ключевые слова явно, мой код не будет автоматически «обновляться», если допустимые ключевые слова Frameдолжны были измениться.

*args, аналогично, позволяет включать произвольные позиционные аргументы в search:

def search(self,*args):

Python устанавливает args в список, содержащий все позиционные аргументыотправлено на search при вызове search.

Я использовал * аргументы здесь, потому что self.search вызывается без аргументов или одного аргумента.

Когда вы говорите

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

self.search() вызывается без аргументов при нажатии кнопки.Но когда вы говорите,

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

self.search(event) вызывается с одним аргументом при нажатии клавиши Return.event - это Tkinter.Event , который имеет атрибуты (время, состояние, тип, виджет, x, y и т. Д.), Которые позволяют вам узнать больше о том, какое событие произошло.

Другой, возможно, лучший способ определить search был бы

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

Это дало бы понять, что search может быть передано 0 или 1 аргумент, а не просто и произвольное количество аргументов.Это также обеспечило бы более легкий доступ к event, если бы событие было передано search.

Ссылка:

...