【发布时间】:2015-11-07 23:20:39
【问题描述】:
我在使用 tkinter 的界面窗口的关闭按钮时遇到了一些问题。我的工具实时显示一些视频,我使用 after 函数无限循环来实现。
当我通过单击十字关闭 tkinter 窗口时,程序会冻结。但是,当我单击按钮时,会调用相同的函数但它会正确关闭。
这是我为向您展示问题而提出的最简化的代码。有人有解释和解决方法吗?
(顺便说一句,我在 OSX 上使用 Python 2.7.8)
from Tkinter import *
from PIL import Image, ImageTk
import numpy as np
class Test():
def __init__(self, master):
self.parent = master
self.frame = Frame(self.parent)
self.frame.pack(fill=BOTH, expand=1)
self.mainPanel = Label(self.frame)
self.mainPanel.pack(fill=BOTH, expand=1)
self.closeButton = Button(self.frame, command=self.closeApp)
self.closeButton.pack(fill=BOTH, expand=1)
def closeApp(self):
print "OVER"
self.parent.destroy()
def task(tool):
print 'ok'
im = Image.fromarray(np.zeros((500, 500, 3)), 'RGB')
tool.tkim = ImageTk.PhotoImage(im)
tool.mainPanel['image'] = tool.tkim
root.after(1, task, tool)
def on_closing():
print "OVER"
root.destroy()
root = Tk()
root.wm_protocol("WM_DELETE_WINDOW", on_closing)
tool = Test(root)
root.after(1, task, tool)
root.mainloop()
现在,如果您再次尝试使用较小的图像(例如 100*100),它可以工作。或者,如果您在 after 函数中放置 100 的延迟,它也可以工作。但是在我的应用程序中,我需要一个非常短的延迟时间,因为我正在显示一个视频并且我的图像大小是 900px*500px。
谢谢!
编辑(08/19):我还没有找到解决方案。但我可以使用root.overrideredirect(1) 删除关闭按钮,然后在 Tk 中重新创建它,并使用以下方法添加拖动窗口:Python/Tkinter: Mouse drag a window without borders, eg. overridedirect(1)
编辑(08/20):实际上,我什至不能拖动窗口。该工具也冻结了!
【问题讨论】:
-
stackoverflow.com/a/17016127/4731042 另见 Bryan Oakley:“我建议不要在 1ms 后使用 after,除非你真的需要每秒执行 1000 次。”在stackoverflow.com/questions/28047746/…
-
感谢您的链接。就我而言,它无限期地冻结,可能是因为无限循环。如果只是为了任务函数的递归而冻结,那根本不是问题。布莱恩奥克利可能是对的。问题是我真的需要延迟