Tkinter привязывает функцию с аргументами к виджету - PullRequest
9 голосов
/ 04 сентября 2011

У меня есть рамка tkinter и прикрепленная к ней кнопка:

from tkinter import *

def rand_func(a,b,c,effects):
    print (a+b+c)

root=Tk()
frame=Frame(root)
frame.bind("<Return>",lambda a=10, b=20, c=30: rand_func(a,b,c))
frame.pack()

button=Button(frame, text="click me", command=lambda a=1,b=2,c=3,eff=None:rand_func(a,b,c))
button.pack()

root.mainloop()

Я хочу, чтобы та же функция выполнялась, когда пользователь нажимает клавишу ввода и когда он нажимает кнопку. К сожалению, приведенный выше код выдает ошибку при привязке кадра. Кто-нибудь знает решение этой проблемы?

Ответы [ 2 ]

17 голосов
/ 04 сентября 2011

Когда вы создаете привязку с bind, Tkinter автоматически добавляет аргумент, содержащий информацию о событии. Вам нужно будет учесть это либо в вашем rand_func определении, либо в том, как вы его называете.

Этот аргумент не включается при использовании атрибута command. Вы должны позаботиться о том, чтобы учесть этот дополнительный аргумент либо в том, как вы вызываете функцию в каждом случае, либо в том, как функция интерпретирует ее параметры.

Вот одно решение, которое использует lambda в привязке, чтобы принять дополнительное событие только при использовании команды bind, но не передавать его в последнюю команду.

import tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.frame = tk.Frame(self)
        self.frame.pack()
        self.button = tk.Button(self.frame, text="click me",
                             command=lambda a=1, b=2, c=3: 
                                self.rand_func(a, b, c))
        self.button.pack()
        self.frame.bind("<Return>", 
                        lambda event, a=10, b=20, c=30: 
                            self.rand_func(a, b, c))
        # make sure the frame has focus so the binding will work
        self.frame.focus_set()

    def rand_func(self, a, b, c):
        print "self:", self, "a:", a, "b:", b, "c:", c
        print (a+b+c)

app = SampleApp()
app.mainloop()

При этом редко упоминается, что привязка к фрейму - это то, что нужно. Обычно кадр не имеет фокуса клавиатуры, и если у него нет фокуса, привязка никогда не сработает. Если вы устанавливаете глобальное связывание, вы должны либо связать его с тегом «all» (используя метод bind_all ), либо с виджетом верхнего уровня.

2 голосов
/ 04 сентября 2011

Как насчет:

import tkinter as tk


def rand_func(eff=None, a=1, b=2, c=3):
    print(a + b + c)

root = tk.Tk()
root.bind("<Return>", lambda eff: rand_func(eff, a=10, b=20, c=30))

frame = tk.Frame(root)
frame.pack()

button = tk.Button(frame, text="click me",
                   command=lambda: rand_func(None, 1, 2, 3))
button.pack()

root.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...