撤回时,Tkinter不会更新

时间:2018-01-30 16:46:25

标签: python canvas tkinter

我有一个程序,当我的键盘上按下热键时,它会在屏幕上显示图像。根据按下的键,将显示不同的图像。 在没有输入3秒后,我的根Tk获得withdraw() n,因此屏幕上没有任何内容。

现在,每当我想要显示图像时,我都会调用此函数:

    def drawOverlay(self, index):
        self.canvas.itemconfig(self.overlayWidget, image=self.overlayImages[index])
        self.deiconify()

问题是我在更换前会看到旧图像几毫秒。

我试图找出为什么只有在我切换图片后才deiconify()发生延迟事件并且遇到this answer建议使用root deiconify()来调用after() self.after(1000, self.deiconify()) 。我试过了,当它还没有工作的时候,我一直在打电话,发现那个叫

Tk

导致旧图像出现1秒钟,之后将其替换为新图像。

这让我相信Canvaswithdraw()无法在deiconify n时更新。有没有办法解决?我希望在显示图像之前有一个短暂的延迟,而不是在屏幕上闪烁几帧的旧图像,但我不知道如何实现这一点。

修改:所以我实际上是在调用after,而不是仅仅因为包裹而将其传递给-transparentcolor。 这确实修复了持续时间内出现的旧图像,但没有修复闪烁。

Edit2 :我设法使用以下代码重现此问题。

按键盘上的任意键都会显示绿色的直尺。等待它消失然后按另一个键将显示一个红色矩形。

有时只能看到闪光发生,所以尝试几次。我没有设法在overrideredirect未设置时重现,但我无法判断这是由于选项是问题还是由于渲染时间缩短导致问题几乎不可接受。它也更容易看到-transparentcolor已设置。

Edit3 :我通过使用实际图片进一步降低了代码。即使没有按键或附加事件回调,此代码也会在移动图像之前产生黑色闪光。 overrideredirect(True)update()似乎对重现这一点至关重要。手动调用from tkinter import Tk, Canvas from PIL import ImageTk, Image TRANSCOLOR = "blue" IMAGE_SMALL = "overlay.png" IMAGE_LARGE = "overlayRaw.png" class Overlay(Tk): def __init__(self): Tk.__init__(self) self.rawImage = Image.open(IMAGE_SMALL) self.image = ImageTk.PhotoImage(self.rawImage) self.canvas = Canvas(self, width = self.rawImage.size[0], height = self.rawImage.size[1]) self.canvas.pack() self.wm_attributes('-transparentcolor', TRANSCOLOR) # If disabled stops the flashes from ocurring even on large images. self.overrideredirect(True) # If disabled the Windows animation for opening windows plays. Stops the flashing from ocurring self.withdraw() self.overlayWidget = self.canvas.create_image(0, 0, image = self.image, anchor = "nw") self.deiconify() # Flashes Clearly Everytime ## self.update_idletasks() ## self.deiconify() # Only Flashes Sometimes. Always flashes on large images ## self.update() ## self.deiconify() # Only Flashes Sometimes. Always flashes on large images ## self.after(0, self.deiconify) # Flashes Clearly everytime ## self.after(200, self.deiconify) # Only Flashes Sometimes. Always flashes on large images ## self.update() ## self.after(200, self.deiconify) # Flashes Clearly Everytime o = Overlay() o.mainloop() 之前会降低此次发生的频率,但仍会导致较大图像的闪烁。这表明渲染时间是其中一个因素。

overlay.png

overlayRaw.png

git rebase -i HEAD~2

1 个答案:

答案 0 :(得分:0)

我没有看到太多可能导致闪烁的事情。我的建议是在调用self.update之前添加对deiconify的显式调用。这应该指示tkinter重绘画布上的所有内容。但是,如果您的平台上的tkinter延迟绘制直到窗口被映射,那将无济于事。

尝试替换它:

self.after(0,self.deiconify)
self.after(2000, self.hideOverlay)

用这个:

self.update()
self.deiconify()