【问题标题】:python/tkinter screen stops displaying canvas updatespython/tkinter 屏幕停止显示画布更新
【发布时间】:2018-08-25 22:59:39
【问题描述】:

我有一个程序可以更新(完整的图像重新创建,即旋转图像),然后更改 tkinter.canvas.image,然后调用 canvas.updatestats() 以强制更改屏幕。 time.sleep(0.0001) 被调用并且过程重复自身。

直到鼠标指针变为一个蓝色的小圆圈,并且在蓝色圆圈周围有一个浅色条,它才能完美运行。如果我移动鼠标指针,圆圈会相应移动。可能 30 秒后,圆圈返回到鼠标指针,屏幕立即变为运行 30 秒后的样子(此时屏幕 100% 正确运行 30 秒)。然而,在蓝色圆圈出现期间,屏幕不再更新。我怀疑可能是垃圾收集已经开始并导致 tkinter 正常工作但屏幕更新被暂停。这需要一段时间才能开始,但之后经常发生。

我尝试导入 gc。然后执行 gc.disable() 但这没有帮助。

有人确切知道为什么会这样吗?

有没有办法阻止这种情况发生?

我的程序能否确定正在停止屏幕更新,因此我可以暂停屏幕更新直到完成?

【问题讨论】:

  • 不知道你的代码是什么样子很难说。您可以发布一个重现此问题的minimal reproducible example 吗?顺便说一句,在 GUI 程序中调用 time.sleep 通常不是一个好主意,因为这会使 everything 进入睡眠状态,因此 GUI 无法自行更新或响应用户输入。我猜 0.1 毫秒的延迟不会造成任何伤害,OTOH,.sleep 如果系统繁忙,睡眠时间可能会比请求的时间长。
  • 不,我不能。仅仅为了设置达到这一点所需的所有数据结构,可能需要大约一千行代码。

标签: python tkinter garbage-collection tkinter-canvas mouse-cursor


【解决方案1】:

这是发生问题时正在执行的循环。记住代码可以工作并产生正确的输出,除了当蓝色圆圈替换鼠标指针时,代码继续正确执行,只是在 30 秒延迟期间屏幕没有更新并且蓝色圆圈最终消失显示 30 秒执行的最终结果。没有在我的代码中更改鼠标指针的位置。

这是一台 Windows 10 机器和 python 3.6。

    while (fx != tx or fy != ty):
        if fx == tx:
            dx = 0
        elif fx > tx:
            dx = -2 if fx != tx+1 else -1
        else:
            dx =  2 if fx != tx-1 else  1
        if fy == ty:
            dy = 0
        elif fy > ty:
            dy = -2 if fy != ty+1 else -1
        else:
            dy =  2 if fy != ty-1 else  1
        steps += 1
        if steps > 0:
            if sAngle != eAngle:
                if eAngle < sAngle: sAngle -= 2
                else:               sAngle += 2
                im = Image.new("RGBA",(int(tileHeight+tileWidth/2),int(tileHeight+tileWidth/2)))
                if til.direction == North or til.direction == South:
                    im.paste(til.dom.raw[til.direction],(int((tileHeight+tileWidth/2-tileWidth)/2),int(tileWidth/4)))
                else:
                    im.paste(til.dom.raw[til.direction],(int(tileWidth/4),int((tileHeight+tileWidth/2-tileWidth)/2)))
                im = im.rotate(sAngle)
                imm = ImageTk.PhotoImage(im)        
                CANVAS.delete(til.canvasID)
                tags.remove(til.canvasID)
                til.canvasID = CANVAS.create_image(fx,fy,anchor=tk.CENTER,image=imm)
                tags.append(til.canvasID)

        CANVAS.move(til.canvasID,dx,dy)
        fx += dx
        fy += dy
        CANVAS.update_idletasks()
        time.sleep(0.0000001)

【讨论】:

  • 此信息不是答案,它是您问题的一部分,因此它属于您的问题,而不是答案部分。
  • 但无论如何,我在这里看不到任何会导致您的问题的东西。但是,您可以使该代码更有效率。不要删除画布图像项并创建一个新项。只需更新现有图像项的photo 属性即可。
猜你喜欢
  • 1970-01-01
  • 2018-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
  • 1970-01-01
相关资源
最近更新 更多