【问题标题】:python canvas.coord() accumulate memorypython canvas.coord() 积累内存
【发布时间】:2016-06-03 14:09:47
【问题描述】:

我用 tkinter 制作了一个简单的模拟时钟来研究 python GUIing。代码如下:

from tkinter import *
from datetime import datetime
import threading
from math import cos, sin, pi

root = Tk()
root.geometry('400x400')
pause = True

def sec_to_coord(second):
    x = cos((second - 15) * pi / 30)
    y = sin((-second - 15) * pi / 30)
    return x,y

def update():
    global pause
    if pause: return
    threading.Timer(1, update).start()
    now = datetime.now()
    x,y = sec_to_coord(now.second)
    canv.coords(line, 200, 200, x * 100 + 200, y * 100 + 200) # drains RAM
    x,y = sec_to_coord(now.minute + now.second / 60)
    canv.coords(minhand, 200, 200, x * 90 + 200, y * 90 + 200) # drains RAM
    x,y = sec_to_coord(now.hour * 5 + now.minute / 12)
    canv.coords(hourhand, 200, 200, x * 50 + 200, y * 50 + 200) # drains RAM
    print(':'.join([str(now.hour), str(now.minute), str(now.second)]))

def start():
    global pause
    if not pause: return
    pause = False
    print('pause =', pause)
    update()

def halt():
    global pause
    if not pause: 
        pause = True
        print('pause =', pause)

def on_closing():
    halt()
    print('BUY-BUY!')
    root.destroy()

canv = Canvas(root, width=400, height=400)
canv.pack()
line = canv.create_line(200, 200, 200, 100)
minhand = canv.create_line(200, 200, 200, 110, width = 3)
hourhand = canv.create_line(200, 200, 200, 150, width= 7)
ticks = []
for i in range(60):
    x,y = sec_to_coord(i)
    if i % 5 == 0:
        ticks.append(canv.create_line(x*90+200, y*90+200, \
            x*100+200, y*100+200, width=3))
    else:
        ticks.append(canv.create_line(x*95+200, y*95+200, \
            x*100+200, y*100+200, width=3))

root.protocol('WM_DELETE_WINDOW', on_closing)
start()
root.mainloop()

问题是:在滴答作响的同时,时钟会累积 RAM。通过注释部分代码,我发现def update(): 中的canv.coord() 函数负责。 请问有人能告诉我代码有什么问题吗?

【问题讨论】:

  • tkinter 不是线程安全的。在 tkinter 中有一些不需要线程的简单动画制作技术。
  • @BryanOakley:tkinter 是否(而不是预期)“线程安全”似乎取决于术语的定义和 Python 版本。请参阅 bugs.python.org/issue11077 和 Martin 的 cmets,以及 bugs.python.org/issue16823。我报告在 2.7 中失败的线程 tkinter 代码在 3.5 中有效。
  • 使用 root.after(1000, update) 代替 Timer 调用。它使用 tk 循环或多或少地做同样的事情。使用root.after 动画查看其他答案。

标签: python user-interface memory-leaks tkinter


【解决方案1】:

谢谢你,特里!!!这解决了问题!我不得不按照你的建议只更改一行 root.after(1000, update) 而不是 threading.Timer(1, update).start() 并且 RAM 积累消失了!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-05
    • 2021-03-24
    • 1970-01-01
    • 2010-10-05
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    相关资源
    最近更新 更多