我有一个使用tkinter的Python 3.5应用程序,并在动画中创建/删除小部件。我注意到,当在窗口调整大小的回调期间使用w.destroy()销毁窗口小部件时,回调正确完成,但窗口正在重置为其原始大小。
我试图使用self.after(1000,self.resize)来延迟w.destroy()并且那种关闭工作但是当在回调被触发时向下拖动/保持光标时,调整大小无论如何都会跳回来。
有人建议动态删除小部件并释放内存吗?
更新 作为一种解决方法,我使用w.delete = True标记要删除的小部件,并在'之后标记。回调删除标记为删除的小部件。
这是一个简化的样本来说明问题:
更新:简化代码以减少重现问题。
from tkinter import ALL, N, E, W, S, Canvas, Tk, ttk
class Resize(Tk):
def __init__(self):
super().__init__()
self.init = True
self.canvas = None
self.position_window()
self.create_canvas()
def resize(self):
if self.init:
self.init = False
return
# delete(ALL) will remove the widget from the display, but widget
# remains in memory as child of canvas. Resizing works ok.
self.canvas.delete(ALL)
# widget.destroy() will release memory of widget, but blocks/resets resizing.
# Window gets resized by 1-2 pixels and jumps back to its original size.
[child.destroy() for child in self.canvas.winfo_children()]
def create_canvas(self):
self.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.canvas = Canvas(self)
self.canvas.grid(row=0, column=0, sticky=(N, S, W, E))
self.canvas.bind('<Configure>', lambda *args: self.resize())
entry = ttk.Label(self.canvas, text='Some dummy text')
self.canvas.create_window(20, 20, window=entry, anchor='w')
def position_window(self):
self.resizable(1, 1)
sceenwidth = self.winfo_screenwidth()
screenheight = self.winfo_screenheight()
self.update_idletasks()
width = 600
height = 300
left = sceenwidth / 2 - width / 2
top = (screenheight / 2 - height / 2) / 3
self.geometry("%dx%d%+d%+d" % (width, height, left, top))
if __name__ == '__main__':
Resize().mainloop()
答案 0 :(得分:0)
我没有尝试你的代码,但我对自己的项目有同样的问题。
窗口不仅仅是在destroy()
上调整大小/重置; <Configure>
事件似乎被打断了。
无论我调整多少或多少,窗口总会恢复到第一个<Configure>
回调。因此,或者与此一起,Button-1自动释放,防止窗口调整大小的手柄跟随鼠标。
换句话说,窗口边缘是&#34;滑出&#34;从鼠标下方开始,就像Windows中的滚动条会在鼠标移动太远时重置中间滚动。
无论如何,解决方案是使用ttk.Sizegrip并禁止使用窗口边框调整顶层窗口的大小。
答案 1 :(得分:0)
https://stackoverflow.com/a/65605907/7281120
我在别处回答了这个问题。我结束了投票
win32api.GetKeyState(0x01) >= 0
并存储释放鼠标时要销毁的物品列表,这样做是安全的。