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:

enter image description here

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

Popular posts from this blog

cakephp - simple blog with croogo -

How to group boxplot outliers in gnuplot -

bash - Performing variable substitution in a string -