【问题标题】:Change the colour of a tkinter button generated in a loop更改循环中生成的 tkinter 按钮的颜色
【发布时间】:2020-01-10 03:02:46
【问题描述】:

在 python tkinter 中,我有一个程序可以生成多个按钮,默认 fg 为红色

from tkinter import *

root = Tk()

def dothis(i):
    print(i)
    button.config(fg='green')

for i in range(5):
    button = Button(root, width=30, text="button{}".format(i), command=lambda i=i: dothis(i))
    button.config(fg='red')
    button.pack()

这会创建这个窗口:

在这个程序中,我试图让它一旦按下按钮,文本的颜色 (fg) 就会变成绿色。相反,当调用dothis(i) 时,它会将最后生成的按钮的颜色更改为绿色。这不是我想要的。 总而言之,当我点击 button3 时,我想看到这个:

但是相反,我看到了这个(最后生成的按钮被修改了,不是我想要的那个):

我怎样才能解决这个问题,同时仍然保持循环生成的按钮? 注意:更改颜色后按钮也必须是可修改的,例如一旦变成绿色,它就可以变回红色。

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    您得到了正确的lambda 表达式,但您传递的参数与您创建的按钮无关。您应该将 Button 小部件作为参数传递:

    from tkinter import *
    
    root = Tk()
    
    def dothis(button):
        button.config(fg='green')
    
    for i in range(5):
        button = Button(root, width=30, text="button{}".format(i))
        button.config(fg='red', command=lambda i=button: dothis(i))
        button.pack()
    
    root.mainloop()
    

    要实现红绿切换,可以使用三元运算符:

    def dothis(button):
        button.config(fg='green' if button["foreground"]=="red" else "red")
    

    【讨论】:

      【解决方案2】:

      如果你坚持除了最后一个按钮之外的所有按钮都是匿名的,并且使用command而不是绑定事件,你可以使用partials:

      from tkinter import *
      from functools import partial
      
      root = Tk()
      
      button_callbacks = {}
      
      def on_click(button):
          button.config(fg="green")
      
      for i in range(5):    
          button = Button(root, width=30, text=f"button{i}", fg="red")
          callback_name = f"on_click_{i}"
          button_callbacks.update({callback_name: partial(on_click, button=button)})
      
          button.config(command=button_callbacks[callback_name])
          button.pack()
      

      使用事件绑定会更直接一些,但其行为与使用command 触发回调并不完全相同。这可能是这样的:

      from tkinter import *
      
      root = Tk()
      
      def on_click(event):
          button = event.widget
          button.config(fg="green")
      
      for i in range(5):    
          button = Button(root, width=30, text=f"button{i}", fg="red")
          button.bind("<Button-1>", on_click)
          button.pack()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-22
        • 2018-05-30
        • 1970-01-01
        • 2016-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多