Tkinter 画布对象 tag_bind 导致内存泄漏

问题描述 投票:0回答:1

如果我在程序运行时监视 Windows 任务管理器,我会看到内存使用量持续上升。我编写了随附的代码来演示该问题。一旦将 tag_bind 添加到画布上,无论我如何尝试解除画布对象的绑定,内存使用量都不会下降,并且连续的绑定会要求越来越多的内存使用量。 我已经运行绑定语句数千次以放大效果。

我的代码:

from tkinter import *

import os, psutil
process = psutil.Process(os.getpid())
def showmem(): print(f'{process.memory_info().rss:,}')

root = Tk()

canvas = Canvas(root)

def bind_one(canvas, r) :
    canvas.tag_unbind(r, "<ButtonPress-1>") #This has no effect on memory
    
    def procedure(r, event) : print(r,event)    
    canvas.tag_bind(r, "<ButtonPress-1>", lambda event : procedure(r,event))

def unbind_all(R, canvas) :
    for r in R : canvas.tag_unbind(r, "<ButtonPress-1>")
    showmem()
Button(root, text = 'unbind', command = lambda : unbind_all(R, canvas)).grid()

def rebind_all(R, canvas) :
    def procedure(r, event) : print(r,event)
    for r in R : canvas.tag_bind(r, "<ButtonPress-1>", lambda event, r = r : procedure(r, event))
    showmem()
Button(root, text = 'rebind', command = lambda : rebind_all(R, canvas)).grid()

R = []
s = 50
for j in range(6) :
    for k in range(6) :
      R += [canvas.create_rectangle(k*s,j*s,(k+1)*s,(j+1)*s, fill = 'white')]

x1, y1, x2, y2 = canvas.bbox('all')
canvas.config(width=x2, height=y2)
    
showmem()

count = 0
for k in range(2000) :
    for r in R : bind_one(canvas, r)  #line A
    if count == 100 :
        showmem()
        count = 0
    count += 1

showmem()               
   
canvas.grid()

mainloop()
tkinter canvas memory-leaks bind
1个回答
0
投票

内存泄漏是由于 tkinter 画布更新速度太快造成的。遗憾的是,尽管您可以采取一些措施来缩小泄漏,但没有直接解决此问题的方法。

可能的修复:

您可以使用不同的 GUI 模块,例如 PyQT5,内存泄漏较少,或者您可以通过删除一些事件检查来减轻更新的负担。

这就是我能提供的一切。如果不使用武断的方法,就无法解决效率低下的问题。 :) 我希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.