我正在尝试在Python中创建一个按钮(导入Tkinter),每次单击后都会改变颜色

时间:2011-11-15 23:09:33

标签: python tkinter

我正在尝试在Python中创建一个按钮(使用Tkinter),每次单击它时都会改变颜色。到目前为止我有这个:

from Tkinter import *

class Application(Frame):

    def __init__(self, master):
        Frame.__init__(self, master)
        self.grid()
            #initialize frame
        self.create_widgets()
        self.bttn_clicks = 0
            #initiates button clicks

    def create_widgets(self):
        self.bttn1 = Button(self)
        self.bttn1["text"] = "Click Me!"
        self.bttn1["command"] = self.update_count
        self.bttn1.grid()
            #creates button

    def update_count(self):
        if self.bttn_clicks + 1:
            self.bttn1.configure(background = "blue")
        if self.bttn_clicks + 2:
            self.bttn1.configure(background = "green")
        if self.bttn_clicks + 3:
            self.bttn1.configure(background = "orange")
        if self.bttn_clicks + 4:
            self.bttn1.configure(background = "red")
        if self.bttn_clicks + 5:
            self.bttn1.configure(background = "yellow")
            #changes colors from blue, to green, orange, red, then yellow

root = Tk()
root.title("Color Button")
root.geometry("200x85")
app = Application(root)
root.mainloop()

如果有人可以提供帮助,我将非常感激。另外,我是编程和Python的新手,我刚开始在3天前使用Tkinter - 所以请记住这一点。

2 个答案:

答案 0 :(得分:4)

Python有iterators。它们与列表类似,但迭代器中的项是在需要时生成的,而不是在定义时完整枚举。下面是一个无限迭代器的示例,它通过使用itertools.cycle

包装元组来实现
In [119]: import itertools

In [120]: color=itertools.cycle(('blue', 'green', 'orange', 'red', 'yellow'))

In [121]: color
Out[121]: <itertools.cycle object at 0x9a1846c>

您可以通过对其应用next函数从迭代器中提取值:

In [122]: next(color)
Out[122]: 'blue'

In [123]: next(color)
Out[123]: 'green'

如果我们要继续调用next足够的时间,迭代器将会到达yellow,然后再循环回来再次产生blue。因此它是一个无限的迭代器,它完美地描述了我们想要的按钮颜色,而不必弄乱任何计数器变量。

因此,您可以使用此迭代器,而不是使用self.bttn_clicks进行计数:

import Tkinter as tk
import itertools

class App(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self,master)
        self.master=master
        self.grid()
        self.colors=itertools.cycle(('blue', 'green', 'orange', 'red', 'yellow'))
        self.bttn1=tk.Button(self, text='Click Me!', bg=next(self.colors),
                             command=self.change_color)
        self.bttn1.grid()
    def change_color(self):
        color=next(self.colors)
        self.bttn1.configure(background=color)

root=tk.Tk()
root.title('Color Button')
root.geometry('200x85')
app=App(root)
root.mainloop()

请注意,当鼠标悬停在按钮上时,该按钮会突出显示。因此,当您单击按钮时,它看起来是灰色的。您必须将鼠标从按钮上移开才能看到颜色。


代码

if self.bttn_clicks + 1:

告诉Python评估表达式self.bttn_clicks + 1。由于self.bttn_clicks从0开始,因此该表达式等于1.在Python中,0被认为是布尔值false,而所有其他数字都是布尔值true(偶数float('nan')float('inf')!)。因此,if self.bttn_clicks + 1评估为Trueif-block已执行。

因此按钮设置为蓝色:

self.bttn1.configure(background = "blue")

接下来是条件

if self.bttn_clicks + 2:

评估为0+2,相当于2,再次为True, 所以下一个if-block也会被执行。现在按钮设置为绿色。等等。

显然,这不是我们想要的。相反,将self.bttn_clicks的值递增1,但当它超过与最后一种颜色相对应的索引时,它会回绕到零(请参阅与使用迭代器相比有多么费力?):

self.bttn_clicks=(self.bttn_clicks+1)%5

并测试哪个值self.bttn_clicks现在等于:

   if self.bttn_clicks == 0:
        self.bttn1.configure(background = "blue")
   elif self.bttn_clicks == 1:
        self.bttn1.configure(background = "green")
   ...

答案 1 :(得分:1)

在编辑问题之前,您没有保存对按钮的引用,因此无法在以后修改它。为了能够修改窗口小部件,您需要保存对它的引用。然后,稍后您可以使用configure方法修改它以更改其颜色:

self.bttn1 = Button(...)
...
self.bttn1.configure(background = "red"