我如何使此代码执行应做的工作?

时间:2018-07-30 16:18:53

标签: python for-loop tkinter colors background

所以,我要尝试的是打开窗口时,它启动一个过程,在此过程中,每0.2秒它会更改颜色的第一个和第三个值(在该过程中,它将范围的元素转换为十六进制)值,然后是字符串)从rgb(86,32,86)转到rgb(126,32,126)。尽管我认为这可能行得通,但事实并非如此。我只有第一种颜色的背景,仅此而已。

from tkinter import *
import time

root = Tk()
for i in range(86,126):
    h = hex(i)
    h = str(h)
    h = h[2] + h[3]
    root.configure(background=("#" + h + "32" + h ))
    time.sleep(0.2)

root.mainloop()

2 个答案:

答案 0 :(得分:0)

必须使用after函数使窗口系统有时间处理更新。像在主线程上那样在循环中调用窗口更新功能会锁定窗口,直到循环终止。

尝试将for循环中的代码移至新函数中,例如updateBackground,并使用after使其递归调用:

def updateBackground(i):
    # ...
    if i < 126:
        root.after(200, lambda: updateBackground(i + 1))

请注意,我使用lambda来递增i。

信用:https://stackoverflow.com/a/36670519/1757964

答案 1 :(得分:0)

此代码的主要问题是使用sleep()。因为Tkinter是单线程应用程序,并且是事件驱动的,所以当您使用sleep()时,最终将发生整个Tkinter实例冻结。

要解决此问题,Tkinter提供了一种称为After()的方法,该方法旨在安排事件在一段时间后发生。因此,要获得与睡眠有关的相同影响,我们可以创建一个函数,该函数可以在0.2秒后调用自身,并为其提供开始编号和结束编号。

from tkinter import *


root = Tk()

def do_something(start_number, end_number):
    if start_number <= end_number:
        h = str(hex(start_number))[2:] # combined all your work on h to one line
        root.configure(background=("#{}32{}".format(h, h)))
        start_number += 1
        root.after(200, do_something, start_number, end_number)

do_something(86, 126)

root.mainloop()

请注意,颜色变化不大,很难看到。如果增加`end_number认为会更明显。