Получить виджет, который вызвал событие? - PullRequest
9 голосов
/ 29 ноября 2010

В Tkinter у меня есть несколько виджетов, привязанных к левой кнопке мыши.Все они вызывают одно и то же событие при нажатии.

Как мне восстановить, какой виджет был нажат?

Я хочу, чтобы, когда, скажем, Label2 была нажата, я смог восстановить, что Label2 был виджетом, который был нажат в событии, которое он вызвал.

Ответы [ 3 ]

14 голосов
/ 07 декабря 2010
def f(event):
    caller = event.widget
12 голосов
/ 29 ноября 2010

У вас есть пара вариантов. Одним из способов является доступ к атрибуту widget объекта события. Другой способ - передать ссылку на объект в вашу функцию. Вот пример, который использует один из каждого.

import Tkinter as tk

def onClickA(event):
    print "you clicked on", event.widget
    event.widget.config(text="Thank you!")


def onClickB(event, obj):
    print "you clicked on", obj
    obj.config(text="Thank you!")

root = tk.Tk()
l1 = tk.Label(root, text="Click me")
l2 = tk.Label(root, text="No, click me!")
l1.pack()
l2.pack()

l1.bind("<1>", onClickA)
l2.bind("<1>", lambda event, obj=l2: onClickB(event, obj))

root.mainloop()
2 голосов
/ 29 ноября 2010

Похоже, что все ваши виджеты используют общий обработчик событий. Эта выдержка из Tkinter 8.4 Reference Джона У. Шипмана - NM Tech, может помочь.

30,7. Трюк с дополнительными аргументами

Иногда вы хотели бы передать другим аргументы обработчику помимо событие.

Вот пример. Предположим, ваш приложение имеет массив из десяти флажки, чьи виджеты хранятся в списке self.cbList, проиндексированном номер кнопки в range(10).

Предположим, что вы хотите написать один обработчик с именем .__cbHandler для <Button-1> событий во всех десяти эти кнопки проверки. Обработчик может получить актуальный Checkbutton виджет что вызвало его, ссылаясь на .widget атрибут Event объект, который передается, но как он узнает, что кнопка проверки индекс в self.cbList?

Было бы неплохо написать наш обработчик с дополнительным аргументом для номер кнопки, что-то вроде это:

    def __cbHandler ( self, event, cbNumber ):

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

К счастью, способность Python предоставить значения по умолчанию для функции аргументы дают нам выход. Есть посмотрите на этот код:

    def __createWidgets ( self ):
        ?
        self.cbList = [] # Create the checkbutton list
        for i in range(10):
            cb = Checkbutton ( self, ? )
            self.cbList.append ( cb )
            cb.grid( row=1, column=i )
            def handler ( event, self=self, i=i ): # [1]
                return self.__cbHandler ( event, i )
            cb.bind ( "<Button-1>", handler )
        ?
    def __cbHandler ( self, event, cbNumber ):
        ?

# [1] Эти строки определяют новую функцию handler, который ожидает три аргументы. Первый аргумент Event объект передан всему событию обработчики, а второй и третий аргументы будут установлены по умолчанию значения? дополнительные аргументы нам нужно передать его.

Эта техника может быть расширена до поставьте любое количество дополнительных аргументы обработчикам.

Несколько более краткий способ сделать это, как Брайан Оукли для второй кнопки в , его ответ , состоит в том, чтобы определить каждую функцию-обработчик в ряд с лямбда-выражением, т.е.

def __createWidgets ( self ):
    ?
    self.cbList = [] # Create the checkbutton list
    for i in range(10):
        cb = Checkbutton ( self, ? )
        self.cbList.append ( cb )
        cb.grid( row=1, column=i )
        cb.bind ( "<Button-1>", lambda event, self=self, i=i:
                                    self.__cbHandler( event, i ) )
    ?
def __cbHandler ( self, event, cbNumber ):
    ?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...