我在Python(导入Tkinter)中尝试创建一个每次点击后改变颜色的按钮

1 投票
2 回答
2605 浏览
提问于 2025-04-17 06:24

我正在尝试在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 个回答

1

在你编辑问题之前,你没有保存按钮的引用,所以之后就没办法去修改它。要想修改一个小部件,你需要先保存它的引用。然后,你可以使用 configure 方法来改变它的颜色:

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

Python 有一种叫做 迭代器 的东西。它们和列表有点像,但迭代器里的项目是根据需要生成的,而不是在定义时就全部列出来。下面是一个无限迭代器的例子,它是通过用 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 被认为是布尔值的假,而其他所有数字都是布尔值的真(即使是 float('nan')float('inf') 也是如此!)。所以 if self.bttn_clicks + 1 的结果是 True,因此 if-block 会被执行。

这样按钮就被设置为蓝色:

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

接下来条件

if self.bttn_clicks + 2:

被计算为 0+2,这等于 2,这又是 True,所以下一个 if-block 也会被执行。现在按钮被设置为绿色。依此类推。

显然,这不是我们想要的。相反,我们应该把 self.bttn_clicks 的值加一,但当它超过最后一个颜色的索引时要回绕到零(看看这和使用迭代器相比是多么繁琐):

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")
   ...

撰写回答