【问题标题】:customize tkinter menu while menu is open菜单打开时自定义 tkinter 菜单
【发布时间】:2014-04-10 04:08:54
【问题描述】:

我想让不太受欢迎的菜单项从白色逐渐淡入黑色。有没有办法在菜单仍然打开时更新颜色?我已经尝试过 postcommand 和线程:

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()

到目前为止,第一次尝试在菜单出现之前完全运行(这很有意义,因为在发布菜单之前调用了 postcommand),第二次尝试仅在菜单未打开时运行(我不明白)由印刷声明证明。

谁能告诉我如何正确地动态改变颜色以在菜单打开时让项目淡入?

【问题讨论】:

    标签: python user-interface tkinter menu tkinter-menu


    【解决方案1】:

    回调中的after 方法存在一些问题:

    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
    

    首先,如果您将参数传递给在后面调用的函数,您必须使用 lambda 表达式或用逗号分隔它们:

    root.after(100, color, 'black')
    

    否则,括号将首先计算该函数。

    其次,after 不适用于您可能习惯的典型控制流-它没有评估一个,然后是下一个-您在调用后设置两个都在 100 毫秒后评估,所以这就是会发生什么。

    这是一个淡入淡出回调的​​工作示例:

    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()
    

    注意 postcommand 中的 lambda 表达式,这是将参数传递给 fadein() 所必需的。

    更多信息:http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.after-method

    【讨论】:

    • 啊,我了解after 电话 - 谢谢!不过,我尝试了这个例子,对我来说,after 调用直到菜单关闭才开始,所以我看不到淡入(除非我输入的打印语句证明了这一点,它出现在菜单未发布)。你能在打开的菜单中看到它吗?
    • 查看我的编辑以获取完整的工作代码。它可以工作,但会闪烁——它不是从 FFFFFF(白色)开始,而是从 999999(浅灰色)开始,所以变化不那么明显。
    • 有趣 - 我完全复制了您的代码并在我的机器上运行(Mac OS 10.6,python 2.7 兼容),并看到相同的行为直到菜单关闭后才消失。出于好奇,我在具有 python 3.4 的 Windows 7 VM 中尝试了它,它看起来很可爱!我可以指定环境要求,所以这解决了我的问题 - 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 2018-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多