python - Correct way of using root.after and root.mainloop in Tkinter -
i have tkinter interface needs automatically refreshed every 5 minutes. far there no problem, have like:
root.after(300000, function_to_run, args_of_fun_to_run) the problem have "infinite" amount of time. scenario gui running on pc attached tv displaying info 24/7 in office. works around 8 hours , following error:

now, know traceback goes way line in 1 of custom modules uses matplotlib. none of custom modules uses loops knw error not directly come 1 of them (please correct me if i'm wrong), must me repeating function infinite amount of time. code main function:
from tkinter import * tkinter import ttk import logging import datetime import sys sys.path.append(r'c:\users\me\desktop\seprated sla screens') import sla_main sla import main_frame mf import sla_grid sg import incoming_volume iv import outgoing_volume ov import read_forecast fc import get_headers hd import vol_graph vg import out_graph og import add_graph ag import sla_reduction_email 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 rows before making calculations 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 part info graph , 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:") what can modify here avoid error??
thanks!
edit:
as many have suggested, have moved mainloop call outside of main function. las few lines of code now:
try: maininterface(28, 23.5, 6) root.mainloop() except: logging.exception("oops:") the root.after call remains inside function. after running this, closes after 5 minutes. know why mainloop not being called?
how use mainloop , after
in short, correct way make sure call mainloop precisely once, , have periodic function reschedule when it's done working:
root = tk.tk() ... def do_one_iteration(): ... code here ... root.after(300000, do_one_iteration) root.mainloop() remove recursion
the problem in code have call mainloop in same function calls after -- you're creating infinite loop during each iteration of infinite loop. immediate cause of problem. need move call mainloop out of maininterface function called once.
fix memory leak
you need refactor maininterface bit. appears keep creating new widgets without ever destroying old widgets, memory leak. program run out of memory. of course, creating 1 new widget every 5 minutes isn't egregious, add on time app must run 24/7.
it's best update existing widgets rather destroy , recreate them, if are, need more call grid_forget. remove them view, still taking memory. if want delete old widgets, call destroy method.
close file properly
you apparently attempting close file file.close, proper syntax file.close() (note trailing parenthesis)
Comments
Post a Comment