How to bind multiple widgets with one bind in Tkinter?

2024/10/10 8:22:50

I am wondering how to bind multiple widgets with one "bind".

For expample:

I have three buttons and I want to change their color after hovering.

from Tkinter import *def SetColor(event):event.widget.config(bg="red")returndef ReturnColor(event):event.widget.config(bg="white")returnroot = Tk()B1 = Button(root,text="Button 1", bg="white")
B1.pack()B2 = Button(root, text="Button2", bg="white")
B2.pack()B3 = Button(root, text= "Button 3", bg="white")
B3.pack()B1.bind("<Enter>",SetColor)
B2.bind("<Enter>",SetColor)
B3.bind("<Enter>",SetColor)B1.bind("<Leave>",ReturnColor)
B2.bind("<Leave>",ReturnColor)
B3.bind("<Leave>",ReturnColor)root.mainloop()

And my goal is to have only two binds (for "Enter" and "Leave" events) instead of six as above.

Thank you for any ideas

Answer

To answer your specific question on whether you can have a single binding apply to multiple widgets, the answer is yes. It will probably result in more lines of code rather than less, but it's easy to do.

All tkinter widgets have something called "bindtags". Bindtags are a list of "tags" to which bindings are attached. You use this all the time without knowing it. When you bind to a widget, the binding isn't actually on the widget per se, but on a tag that has the same name as the widget's low level name. The default bindings are on a tag that is the same name as the widget class (the underlying class, not necessarily the python class). And when you call bind_all, you're binding to the tag "all".

The great thing about bindtags is that you can add and remove tags all you want. So, you can add your own tag, and then assign the binding to it with bind_class (I don't know why the Tkinter authors chose that name...).

An important thing to remember is that bindtags have an order, and events are handled in this order. If an event handler returns the string "break", event handling stops before any remaining bindtags have been checked for bindings.

The practical upshot of this is, if you want other bindings to be able to override these new bindings, add your bindtag to the end. If you want your bindings to be impossible to be overridden by other bindings, put it at the start.

Example

import Tkinter as tkclass Example(tk.Frame):def __init__(self, *args, **kwargs):tk.Frame.__init__(self, *args, **kwargs)# add bindings to a new tag that we're going to be usingself.bind_class("mytag", "<Enter>", self.on_enter)self.bind_class("mytag", "<Leave>", self.on_leave)# create some widgets and give them this tagfor i in range(5):l = tk.Label(self, text="Button #%s" % i, background="white")l.pack(side="top")new_tags = l.bindtags() + ("mytag",)l.bindtags(new_tags)def on_enter(self, event):event.widget.configure(background="bisque")def on_leave(self, event):event.widget.configure(background="white")if __name__ == "__main__":root = tk.Tk()view = Example()view.pack(side="top", fill="both", expand=True)root.mainloop()

A little bit more information about bindtags can be found in this answer: https://stackoverflow.com/a/11542200/7432

Also, the bindtags method itself is documented on the effbot Basic Widget Methods page among other places.

https://en.xdnf.cn/q/69914.html

Related Q&A

Iterate a large .xz file line by line in python

I have a large .xz file (few gigabytes). Its full of plain text. I want to process the text to create custom dataset. I want to read it line by line because it is too big. Anyone have an idea how to do…

Detect multiple circles in an image

I am trying to detect the count of water pipes in this picture. For this, I am trying to use OpenCV and Python-based detection. The results, I am getting is a little confusing to me because the spread …

Need guidance with FilteredSelectMultiple widget

I am sorry if it question might turn to be little broad, but since I am just learning django (and I am just hobbyist developer) I need some guidance which, I hope, will help someone like me in the futu…

Django: determine which user is deleting when using post_delete signal

I want admins to be notified when certain objects are deleted but I also want to determine which user is performing the delete.Is it possible?This is the code:# models.py # signal to notify admins whe…

Double inheritance causes metaclass conflict

I use two django packages - django-mptt (utilities for implementing Modified Preorder Tree Traversal) and django-hvad (model translation).I have a model class MenuItem and I want to it extends Translat…

Mask area outside of imported shapefile (basemap/matplotlib)

Im plotting data on a basemap of the eastern seaboard of the U. S. and Canada through Matplotlib. In addition to the base layer (a filled contour plot), I overlayed a shapefile of this focus region ato…

Python Glob.glob: a wildcard for the number of directories between the root and the destination

Okay Im having trouble not only with the problem itself but even with trying to explain my question. I have a directory tree consisting of about 7 iterations, so: rootdir/a/b/c/d/e/f/destinationdirThe …

Get datetime format from string python

In Python there are multiple DateTime parsers which can parse a date string automatically without providing the datetime format. My problem is that I dont need to cast the datetime, I only need the dat…

Generating an optimal binary search tree (Cormen)

Im reading Cormen et al., Introduction to Algorithms (3rd ed.) (PDF), section 15.4 on optimal binary search trees, but am having some trouble implementing the pseudocode for the optimal_bst function in…

Pydub from_mp3 gives [Errno 2] No such file or directory

I find myself in front of a wall here, simply trying to load an audio file into pydub for converting it keeps on throwing a "[Errno 2] No such file or directory" error.Naturally I have spent …