我有一个tkinter接口,需要每5分钟自动刷新一次。到目前为止还没有问题,你只需要做如下事情:
root.after(300000, function_to_run, args_of_fun_to_run)
问题是我必须在“无限”的时间内这样做。这种情况下,图形用户界面将运行在一台连接到电视的电脑上,在我的办公室24/7显示一些信息。这项工作大约8小时,然后我得到以下错误:
现在,我知道回溯一直到我的一个自定义模块中使用matplotlib的一行。我的自定义模块没有使用任何循环,因此我知道错误不是直接来自其中一个模块(如果我错了,请纠正我),因此必须是我无限次地重复函数。这是我主要功能的代码:
from tkinter import *
from tkinter import ttk
import logging
import datetime
import sys
sys.path.append(r'C:\Users\me\Desktop\seprated sla screens')
import sla_main as sla
import main_frame as mf
import sla_grid as sg
import incoming_volume as iv
import outgoing_volume as ov
import read_forecast as fc
import get_headers as hd
import vol_graph as vg
import out_graph as og
import add_graph as ag
import sla_reduction_email as sre
###################################
###################################
###################################
###################################
runs = 0
def maininterface(f_size, pic_x, pic_y):
global runs
global root
start = str(datetime.datetime.now().date()) + ' ' + str(datetime.timedelta(hours=6))
screen = sla.slamain(start)
if runs == 0:
root = mf.mainframe(f_size)
sg.sla_grid(screen, f_size, root)
file = open('titles in queue.txt', 'r')
in_q = file.read()
file.close
ttk.Label(root, text=in_q, anchor=CENTER, width=15, font=('times', f_size, 'bold')).grid(column=6, row=2, sticky=E)
if runs > 0:
###################################
#deletes all rows before making the calculations
for label in root.grid_slaves():
if int(label.grid_info()["row"]) > 1:
label.grid_forget()
sg.sla_grid(screen, f_size, root)
file = open('titles in queue.txt', 'r')
in_q = file.read()
file.close
ttk.Label(root, text=in_q, anchor=CENTER, width=15, font=('times', f_size, 'bold')).grid(column=6, row=2, sticky=E)
###################################
#all this part is just info for the graph and the graph
incoming = iv.incomingvolume(start)
outgoing = ov.outgoingvolume(start)
forecast = fc.readforecast()
headers = hd.getheaders()
vg.volgraph(forecast, incoming, headers, pic_x, pic_y)
#og.outgraph(forecast, outgoing, headers, pic_x, pic_y)
ag.addgraph("vol_graph.png", root, 1)
#ag.addgraph("out_graph.png", root, 2)
runs = runs + 1
globals().update(locals())
print(str(datetime.datetime.now()))
root.after(300000, maininterface, f_size, pic_x, pic_y)
root.mainloop()
logging.basicConfig(level=logging.DEBUG, filename='error_log.txt')
try:
maininterface(28, 23.5, 6)
except:
logging.exception("Oops:")
我可以在这里修改什么来避免这个错误??
谢谢!
编辑:
正如许多人所建议的,我已经将主循环调用移到主函数之外。我代码的最后几行现在看起来是这样的:
try:
maininterface(28, 23.5, 6)
root.mainloop()
except:
logging.exception("Oops:")
root.after调用仍保留在函数内部。像这样运行后,5分钟后关闭。有人知道为什么不调用主循环吗?
在函数外部调用主循环。
如何使用
mainloop
和after
简而言之,正确的方法是确保精确地调用
mainloop
一次,然后在周期函数完成工作后重新安排它自己:删除递归
代码中的问题是在调用
after
的同一个函数中调用mainloop
——在无限循环的每次迭代中创建一个无限循环。这是问题的直接原因。您需要将对mainloop
的调用移出maininterface
函数,以便只调用一次。修复内存泄漏
您还需要重构
maininterface
一点。看起来你一直在创建新的小部件而没有破坏旧的小部件,这是一个内存泄漏。最终你的程序将耗尽内存。当然,每五分钟只创建一个新的小部件并不过分,但是随着时间的推移,它会累积起来,成为一个必须24/7运行的应用程序。通常最好是简单地更新现有的小部件,而不是销毁和重新创建它们,但是如果是,您需要做的不仅仅是调用
grid_forget
。所做的只是将它们从视图中移除,但它们仍占用内存。如果确实要删除旧的小部件,请调用destroy
方法。正确关闭文件
显然您试图用
file.close
关闭一个文件,但是正确的语法是file.close()
(注意后面的括号)相关问题 更多 >
编程相关推荐