Привязка к кнопке работает не так, как ожидалось

я связал событие <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 ответов


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

если вы хотите Return для работы в любом месте окна GUI, а затем изменить

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

to

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 называется.

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

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

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

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

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

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

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

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

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

ссылки: