Tkinter w.destroy()阻止/重置窗口大小调整

时间:2016-06-11 19:25:45

标签: python-3.x tkinter window-resize tkinter-canvas

我有一个使用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()

2 个答案:

答案 0 :(得分:0)

我没有尝试你的代码,但我对自己的项目有同样的问题。

窗口不仅仅是在destroy()上调整大小/重置; <Configure>事件似乎被打断了。 无论我调整多少或多少,窗口总会恢复到第一个<Configure>回调。因此,或者与此一起,Button-1自动释放,防止窗口调整大小的手柄跟随鼠标。

换句话说,窗口边缘是&#34;滑出&#34;从鼠标下方开始,就像Windows中的滚动条会在鼠标移动太远时重置中间滚动。

无论如何,解决方案是使用ttk.Sizegrip并禁止使用窗口边框调整顶层窗口的大小。

答案 1 :(得分:0)

https://stackoverflow.com/a/65605907/7281120

我在别处回答了这个问题。我结束了投票

win32api.GetKeyState(0x01) >= 0

并存储释放鼠标时要销毁的物品列表,这样做是安全的。