冰空双刀流 发表于 2017-6-4 14:41:04

python 2.7 tkinter 相关问题求救

在刚大作业,遇到了几个问题,求救!!!!

第一个是,我想在tkinter主事件循环中做一个循环的动画,像这样
class .....:

def blink(self,win):
      if self.blinkFlag:
            #这里是各种操作
            self.win.update()
            sleep(0.005)
            self.blink(win)

def normal(self,win):
      if self.blinkFlag==False:
            self.blinkFlag=True
            self.blink(win)
      elif self.blinkFlag==True:
            self.blinkFlag=False

其中normal是绑定在一个按钮上的类内函数,作用是改变self.blinkFlag的值,这样可以起到控制动画的效果
但是这块东西有两个问题:
第一个是,sleep()函数是用来起到动画效果的,但是如果前面不加win.update()就会卡死,不知道是什么道理
第二个是,这个循环有很大的问题,我试过两种模式,一种是像上面这样的,blink写成递归函数,每次递归判断flag,被终止了就退出。另外一种是用while循环,写成:

def blink(self,win):
      while self.blinkFlag:
            #这里是各种操作
            self.win.update()
            sleep(0.005)

据说用while循环会有冲突,事实上这两种方法在循环次数不多的时候都没问题,次数一多就会溢出。而且如果在循环的过程中强行关闭窗口,就会报一大堆错误,类型是TclError
我觉得这里的解决方法可能需要用到 canvas控件的方法 .after 但是不太会用,求各位大神指导!!!!!!


whdd 发表于 2018-9-30 15:08:22

{:9_227:}

钱闻韬 发表于 2018-10-1 11:42:57

不会问版主吧!!!{:10_256:}

waitforlove 发表于 2018-10-1 21:03:51

本帖最后由 waitforlove 于 2018-10-1 21:17 编辑

win.update()相当于刷新的窗口的意思,你不刷新,其实动画没动而已,永远刚刚创建时候的样子

2418 发表于 2018-10-2 15:50:27

看上去和3没什么区别

学学看看 发表于 2018-10-8 11:15:39

小小小菜菜菜 发表于 2018-12-20 10:24:15

来学习下

小小小菜菜菜 发表于 2018-12-20 17:26:56


来学习下,等待大牛解答

X用户 发表于 2018-12-22 09:00:36

{:5_94:}

考拉熊 发表于 2018-12-22 09:48:18

{:7_138:}

1809228982 发表于 2018-12-22 10:49:57

来看看,学习学习

X用户 发表于 2018-12-22 13:56:44

路过,看看

扩展阅读 发表于 2018-12-24 15:16:16

看看{:10_249:}

winsome8538 发表于 2020-2-22 15:30:30

共同学习

心驰神往 发表于 2020-11-18 14:00:58

没有大佬解答么

象棋爱好者 发表于 2020-11-18 19:56:22

我不会{:10_266:}

某一个“天” 发表于 2025-1-30 22:21:44

用after

惊晓欲仙 发表于 2025-2-2 20:59:48

本帖最后由 惊晓欲仙 于 2025-2-2 21:07 编辑


首先进行问题分析
1. sleep 函数不加 win.update() 会卡死
在 Tkinter 中,主事件循环负责处理各种用户交互和界面更新。当你使用 time.sleep() 时,程序会暂停执行,这会阻塞主事件循环。也就是说,在 sleep 期间,Tkinter 无法处理新的事件(如鼠标点击、窗口重绘等),导致界面看起来像是卡死了。而 win.update() 会手动更新 Tkinter 的事件循环,使得在 sleep 之前界面有机会处理待处理的事件,避免卡死。
2. 递归和 while 循环的问题
递归:递归调用 blink 函数会不断增加调用栈的深度。当循环次数增多时,会导致栈溢出错误,因为 Python 对递归深度有一定的限制。
while 循环:while 循环同样会阻塞主事件循环,使得 Tkinter 无法正常处理其他事件。当你强行关闭窗口时,由于主事件循环被阻塞,Tkinter 无法正确处理窗口关闭事件,从而抛出 TclError 异常。
下面是解决方法(我用after来解决,使用 after 方法可以避免阻塞主事件循环,从而解决界面卡死和异常抛出的问题。同时,由于不会无限递归或使用 while 循环,也不会出现栈溢出的问题。但可以等会小甲鱼哦,甲鱼有可能有其他方法)
import tkinter as tk
import time

class BlinkAnimation:
    def __init__(self, win):
      self.win = win
      self.blinkFlag = False
      # 创建一个按钮
      self.button = tk.Button(win, text="Toggle Blink", command=lambda: self.normal(win))
      self.button.pack()

    def blink(self):
      if self.blinkFlag:
            # 这里是各种操作,例如更新标签文本
            # 示例:假设这里有一个标签
            label = tk.Label(self.win, text="Blinking...")
            label.pack()
            # 使用 after 方法在 5 毫秒后再次调用 blink 函数
            self.win.after(5, self.blink)

    def normal(self, win):
      if self.blinkFlag == False:
            self.blinkFlag = True
            self.blink()
      elif self.blinkFlag == True:
            self.blinkFlag = False

if __name__ == "__main__":
    root = tk.Tk()
    app = BlinkAnimation(root)
    root.mainloop()

有用点点支持,多多评分哦{:5_95:}

惊晓欲仙 发表于 2025-2-2 21:06:09

有用的话评个分吧{:5_96:}

惊晓欲仙 发表于 2025-2-2 21:06:45

惊晓欲仙 发表于 2025-2-2 20:59
首先进行问题分析
1. sleep 函数不加 win.update() 会卡死
在 Tkinter 中,主事件循环负责处理各种用户 ...

大家有用的话评个分吧{:5_96:}
页: [1] 2
查看完整版本: python 2.7 tkinter 相关问题求救