首页 > 解决方案 > 在 tkinter 中运行连续的动画集,中间有中断

问题描述

图形布局

嗨,我在这里的第一篇文章!我是第一次尝试找出问题的程序员。任何帮助都深表感谢。

我正在尝试通过更改四个标签的背景颜色(“闪烁”)来创建“动画”。所以这个想法是让它按顺序闪烁几次,然后暂停以接受用户输入。这个动画用户输入循环重复了几次。

我试图使用 after 方法来做到这一点。但不是按顺序制作动画,而是最后将所有内容组合在一起并一起运行。换句话说,如果我尝试做连续动画,第一次动画在移动到下一个动画之前不会执行

这部分是生成动画序列的地方。

    self.genRandom(3)  # generate random sequence of numbers
    self.createSchedule(3) #relate the random sequence onto image on screen
    self.doanim() #execute animation 


    self.delay=10000  #delay before beginning next animation 
    self.after(self.delay, self.genRandom(3))
    self.after(self.delay, self.createSchedule(3))
    self.after(self.delay, self.doanim())

时间表生成(将序列号与图像相关联)(延迟,标签颜色更改功能)

def createSchedule(self,seqn):
    self.schedule.clear()
    tuple=(2000, self.labelbegin)
    self.schedule.append(tuple)
    #     (10, lambda: self.associateDigLogo())
    for number in self.listSeqn:
        #     (10, lambda: self.associateDigLogo()
        if number == 0:
            self.schedule.extend(((1000,lambda: self.buttonpresswhatsapp(None)), (500, lambda: self.buttonreleasewhatsapp(None))))
        elif number == 1:
            self.schedule.extend(((1000, lambda: self.buttonpressslack(None)), (500, lambda: self.buttonreleaseslack(None))))
        elif number == 2:
            self.schedule.extend(((1000, lambda: self.buttonpressskype(None)), (500, lambda: self.buttonreleaseskype(None))))
        elif number ==3:
            self.schedule.extend(((1000, lambda: self.buttonpresssnapchat(None)), (500, lambda: self.buttonreleasesnapchat(None))))

这部分是执行动画的地方

def doanim(self):

    if len(self.schedule) <= 0:
        return
    self.sched_item = 0

    s = self.schedule[self.sched_item]
    #run the function stored in the schedule
    print(s[0])
    self.after(s[0], self.doanim_helper)


def doanim_helper(self):

    s = self.schedule[self.sched_item]
    # run the function stored in the schedule
    s[1]()

    self.sched_item += 1
    print(self.sched_item)

    if self.sched_item >= len(self.schedule):
        self.after(1000, self.quit)
    else:
        s = self.schedule[self.sched_item]
        self.after(s[0], self.doanim_helper)

上面调用的图形函数示例

def buttonpresswhatsapp(self, event):
    self.whatsapplabel.config(bg="red")

def buttonreleasewhatsapp(self, event):
    self.whatsapplabel.config(bg="white")

标签: python-3.xanimationtkinter

解决方案


根据文档,当函数传递参数时,

在尝试调用之前评估所有参数表达式

因此,在 中self.after(self.delay, self.genRandom(3)),函数调用立即self.genRandom(3)求值,然后将其返回值传递给。这就是为什么“一切都混在一起”,没有预期的延迟。self.after

相反,您希望传递一个可调用的(例如函数对象)作为第二个参数:

self.after(self.delay, lambda: self.genRandom(3))
self.after(self.delay, lambda: self.createSchedule(3))
self.after(self.delay, self.doanim)

self.genRandom是一个函数。函数是一等对象,可以作为参数传递给其他函数。在 Python 中,函数后面的括号会导致调用该函数。


推荐阅读