Reputation: 283
I want to have less popular menu items fade in gradually from white to black. Is there any way to have the colors update while the menu is still open? I've experimented with postcommand and threads:
def update():
def color(c):
animal_menu.config(fg=c)
root.update()
print c
def adapt():
color('white')
root.after(100, color('#6E6E6E'))
root.after(100, color('black'))
## adapt() ##attempt no.1
## thread.start_new_thread(adapt, ()) ##attempt no.2
root = Tk()
menubutton = Menubutton(root, text="Animals")
animal_menu = Menu(menubutton, tearoff=0, postcommand=update)
animal_menu.add_command(label="Lion", command=print_time)
animal_menu.add_command(label="Tiger", command=print_time)
animal_menu.add_command(label="Bear", command=print_time)
menubutton.menu = animal_menu
menubutton["menu"] = menubutton.menu
menubutton.pack()
root.config()
root.mainloop()
So far, the first attempt runs completely before the menu appears (which makes sense as postcommand is called before posting the menu), and the second attempt runs only when the menu is not open (which I don't understand) as evidenced by the print statements.
Could anybody give me a pointer on how to make the color properly dynamically change to have the items fade in while the menu is open?
Upvotes: 1
Views: 980
Reputation: 3964
There's a couple of problems with the after
method in the callback:
def update():
def color(c):
animal_menu.config(fg=c)
root.update()
print c
def adapt():
color('white')
root.after(100, color('#6E6E6E'))
root.after(100, color('black'))
adapt() ##attempt no.1
First, if you're passing arguments to the function being called in the after, you have to use a lambda expression or just split them by a comma:
root.after(100, color, 'black')
Otherwise, the parenthesis will make that function be evaluated first.
Second, after
doesn't work with the typical control flow you're probably used to--it's not evaluated one, then the next--you're setting both after calls to be evaluated after 100ms, so that's what's going to happen.
Here's a working example of a fadein callback:
from Tkinter import *
def fadein(color):
if color < 111111:
animal_menu.config(fg='#000000')
else:
print color
animal_menu.config(fg='#' + str(color))
root.after(100, fadein, color - 111111)
root = Tk()
menubutton = Menubutton(root, text="Animals")
animal_menu = Menu(menubutton, tearoff=0, postcommand=lambda: fadein(999999))
animal_menu.add_command(label="Lion")
animal_menu.add_command(label="Tiger")
animal_menu.add_command(label="Bear")
menubutton.menu = animal_menu
menubutton["menu"] = menubutton.menu
menubutton.pack()
root.config()
root.mainloop()
Note the lambda expression, in postcommand
, which is needed to pass the argument to fadein()
.
More info: http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.after-method
Upvotes: 1