So I have a bunch of text on a canvas in Tkinter and I want to make it so the text color changes when the mouse is hovering over the text. For the life of me I can't figure out how to do it, and there doesn't seem to be a lot of information about Tkinter anywhere.
for city in Cities:
CityText = Cities[i]
board.create_text(CityLocs[CityText][0], CityLocs[CityText][1], text=CityText, fill="white")
CityText = Cities[i]
i = i + 1
That's just my code to place the text on the canvas, although I'm not sure what else to post to get my point across. Is there no 'hover' function or something like that built into Tkinter?
A label can include any text, and a window can contain many labels (just like any widget can be displayed multiple times in a window). You can easily change/update the Python Tkinter label text with the label text property. Changing the label's text property is another way to change the Tkinter label text.
To configure the mouse pointer color, we can specify the cursor value with (cursor type and its color). For example, to change the cursor color in a label widget, we can specify the value as, cursor="plus #aab1212" where "plus" defines the cursor type and #aab1212 is the Hex value of the color.
foreground − Foreground color for the widget. This can also be represented as fg. highlightbackground − Background color of the highlight region when the widget has focus. highlightcolor − Foreground color of the highlight region when the widget has focus.
You can bind arbitrary events (mouse, keyboard, window manager and possibly others) to any widget in Tkinter.
A nice documentation for that is at http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm -
For example, to bind color changes to widgets when mouse hover over them:
import Tkinter
from functools import partial
def color_config(widget, color, event):
widget.configure(foreground=color)
parent = Tkinter.Tk()
text = Tkinter.Label(parent, text="Hello Text")
text.bind("<Enter>", partial(color_config, text, "red"))
text.bind("<Leave>", partial(color_config, text, "blue"))
text.pack()
Tkinter.mainloop()
The use of functools.partial
here allows you to re-use a variable for your text (Label) widget, since you are appending them to a list. If one would settle to simply using lambda you would have a disgusting surprise, as the variable referring to the widget in the body of the lambda function would always point to the last value it had inside the for
loop. functools.partial
"freeze" the variable content at the time it is called, and yields a new function.
However, since you are placing the items in a Canas, you can either set the "fill" and "fillactive" attributes for each item, as in @mgilson's answer, or you can create a more generic class to handle not only hovering, but other events you choose to implement later.
If your class has a __call__
method, you can pass an instance of it to the bind
method of the canvas, so that the resulting object is called for each event on the canvas. In this case, mouse-motion event suffices:
from Tkinter import *
class Follower(object):
def __init__(self,on_color="#fff", off_color="#000"):
self.on_color = on_color
self.off_color = off_color
self.previous_item = None
def hover(self, canvas, item, x, y):
x1, y1, x2, y2 = canvas.bbox(item)
if x1 <= x <= x2 and y1 <= y <= y2:
return True
return False
def __call__(self, event):
canvas = event.widget
item = canvas.find_closest(event.x, event.y)
hovering = self.hover(canvas, item, event.x, event.y)
if (not hovering or item != self.previous_item) and self.previous_item is not None:
canvas.itemconfig(self.previous_item, fill=self.off_color)
if hovering:
canvas.itemconfig(item, fill=self.on_color)
self.previous_item = item
master=Tk()
canvas=Canvas(master)
canvas.pack()
canvas.create_text((40,20),text="Hello World!",fill="black")
canvas.create_text((60,80),text="FooBar",fill="black")
canvas.bind("<Motion>", Follower())
master.mainloop()
(ps. canvas and text placement example borrowed from @mgilson's answer)
Here's a (admittedly) pretty lame example that works on OS-X...
from Tkinter import *
master=Tk()
canvas=Canvas(master)
canvas.pack()
canvas.create_text((20,20),activefill="red",text="Hello World!",fill="black")
master.mainloop()
reference: http://effbot.org/tkinterbook/canvas.htm
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With