Глобальная привязка Tkinter

Можно ли привязать все виджеты к одной команде одной строкой? Было бы неплохо, если бы я мог набирать одну строку, а не делать каждый виджет по отдельности.


person rectangletangle    schedule 02.09.2010    source источник


Ответы (4)


Вы должны использовать метод bind_all в корневом окне. Затем это будет применяться ко всем виджетам (если вы не удалите тег привязки «все» из некоторых виджетов). Обратите внимание, что эти привязки активируются в последнюю очередь, поэтому при желании вы все равно можете переопределить привязку на уровне приложения для определенных виджетов.

Вот надуманный пример:

import Tkinter as tk

class App:
    def __init__(self):
        root = tk.Tk()
        root.bind_all("<1>", self.woot)
        label1 = tk.Label(text="Label 1", name="label1")
        label2 = tk.Label(text="Label 2", name="label2")
        entry1 = tk.Entry(name="entry1")
        entry2 = tk.Entry(name="entry2")
        label1.pack()
        label2.pack()
        entry1.pack()
        entry2.pack()
        root.mainloop()

    def woot(self, event):
        print "woot!", event.widget

app=App()

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

person Bryan Oakley    schedule 02.09.2010
comment
Когда я изменяю <1> на <Key>, работает ли это, если Tinter работает в фоновом режиме? - person Tetsudou; 08.03.2015
comment
@Tetsudou: это будет работать только тогда, когда приложение имеет фокус клавиатуры. - person Bryan Oakley; 08.03.2015

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

person leoluk    schedule 02.09.2010

Вы имеете в виду что-то вроде этого кода, который обрабатывает все события мыши, обрабатываемые одной функцией?

from Tkinter import *

class ButtonHandler:

    def __init__(self):      
        self.root = Tk()
        self.root.geometry('600x500+200+200')

        self.mousedown = False
        self.label = Label(self.root, text=str(self.mousedown))
        self.can = Canvas(self.root, width='500', height='400', bg='white')

        self.can.bind("<Motion>",lambda x:self.handler(x,'motion'))
        self.can.bind("<Button-1>",lambda x:self.handler(x,'press'))
        self.can.bind("<ButtonRelease-1>",lambda x:self.handler(x,'release'))
        self.label.pack()
        self.can.pack()
        self.root.mainloop()

    def handler(self,event,button_event):
        print('Handler %s' % button_event) 
        if button_event == 'press':
            self.mousedown = True
        elif button_event == 'release':
            self.mousedown = False
        elif button_event == 'motion':
            if self.mousedown:               
                r = 5
                self.can.create_oval(event.x-r, event.y-r, event.x+r, event.y+r, fill="orange")
        self.label.config(text=str(self.mousedown))

button_event = ButtonHandler()
person Tony Veijalainen    schedule 02.09.2010

Вы также можете просто определить функцию, которая вызывает все ваши виджеты, и вызвать эту функцию. Или еще лучше создайте класс, который вызывает ваши виджеты в init, и импортируйте класс...

person Alex    schedule 02.09.2010