正确的方式持续更新Tkinter画布项的颜色

1 投票
1 回答
1380 浏览
提问于 2025-04-18 16:01

我想弄明白怎么让一个矩形的颜色不断变化,每次变化之间间隔一秒。目前我有一个简单的函数,它会创建一个窗口,里面有一个方块和一个按钮,每次点击按钮,方块的颜色就会改变:

def junk():
    def random_color():
        red = int(random.random()*256)
        green = int(random.random()*256)
        blue = int(random.random()*256)
        return '#' + ('{:0>#02X}'*3).format(red,green,blue)

    def change_color():
        c.itemconfig(r, fill=random_color())

    x = Tkinter.Tk()
    c = Tkinter.Canvas(master=x)
    c['width'] = 400; c['height'] = 400
    r = c.create_rectangle(0,0,400,400)
    b = Tkinter.Button(master=x, command=change_color)
    b['text'] = 'change color'
    c.pack(); b.pack(); x.mainloop()

我想要的是,点击一次后,颜色能够自动变化。我知道我需要用一个CheckButton,而不是普通的Button,这样一次点击就能开始颜色变化,下一次点击则可以停止它。

另外,这并不是我“真实”代码的结构,这只是我在IDLE命令行中测试的方式。把辅助函数定义在junk函数里面,可以让我一次性看到所有相关代码,而不用写一个完整的类,所以请不要对我的代码风格发表评论,这样做是故意的,快速而简单。

总结一下:我不太确定怎么才能让颜色变化的循环持续运行,同时又能通过按钮点击来启动和停止这个循环。

1 个回答

0

我搞明白了。在我展示我的解决方案之前,我想纠正我之前说的一个错误:我并不需要用一个 Checkbutton 来实现这个功能。我可以通过改变按钮的 'relief' 选项,把一个普通按钮变成一个切换按钮。下面是我的解决方案:

def junk():
    def color_poll():
        global alarm
        c.itemconfig(r, fill=random_color())
        if keep_going:
            alarm = c.after(1000, color_poll)

    def change_color():
        global keep_going, alarm
        if not keep_going:
            keep_going = True
            b['text']='STOP';b['fg']='red';b['relief']=Tkinter.SUNKEN
            color_poll()
        else:
            keep_going = False; c.after_cancel(alarm); alarm = None
            b['text']='GO';b['fg']='green';b['relief']=Tkinter.RAISED

    x = Tkinter.Tk()
    c = Tkinter.Canvas(master=x)
    c['width'] = 400; c['height'] = 400
    r = c.create_rectangle(0,0,400,400)
    global keep_going, alarm
    keep_going = False; alarm = None
    b = Tkinter.Button(master=x, command=change_color)
    b['text'] = 'GO';b['fg']='green';b['font']='Arial 16';b['relief']=Tkinter.RAISED
    c.pack(); b.pack(); x.mainloop()

我使用了同样的 random_color 函数,但我把它移到了外面,因为它其实不需要放在 junk 函数里面。

撰写回答