By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,797 Members | 1,262 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,797 IT Pros & Developers. It's quick & easy.

refresh automatically text wiget tkinter

P: 1
Hi; I created an application that is based on the introduction of data stored in txt files. the content of these files is displayed in text widget
my problem is that I can not get the automatic refresh of the text widget display

the code in python 3.6, and it cutted into several parts :

Expand|Select|Wrap|Line Numbers
  1.  
  2. from tkinter import *
  3. from tkinter.ttk import Notebook
  4. import tkinter.ttk as ttk
  5. import time
  6. #window
  7. root=Tk()
  8. root.geometry('450x350')
  9. root.title('test')
  10. #variables
  11. ent_releves1=StringVar()
  12. ent_releves2=StringVar()
  13.  
part of code for functions

Expand|Select|Wrap|Line Numbers
  1. #Functions:
  2. def archiver():
  3.  
  4.     archive_monitoring={"date" : time.strftime('%d/%m/%y', time.localtime()),  
  5.                   "releves_mesure1": ent_releves1.get(),
  6.                   "releves_mesure2": ent_releves2.get(),                          }
  7.  
  8.     if (ent_releves1.get() !="" ) :
  9.         mon_fichier1 = open("save1/monitor1.txt", "r")
  10.         text1 = mon_fichier1.read()
  11.         mon_fichier1.close()                       
  12.         textInsert1=str(archive_monitoring["date"])+"\t" +str(archive_monitoring["releves_mesure1"])+"\n"
  13.         fileW1 = open("save1/monitor1.txt", "w")
  14.         fileW1.write(textInsert1 + text1)
  15.         fileW1.close()
  16.  
  17.     if (ent_releves2.get() !="" ) :
  18.         mon_fichier2 = open("save1/monitor2.txt", "r")
  19.         text2 = mon_fichier2.read()
  20.         mon_fichier2.close()                       
  21.         textInsert2=str(archive_monitoring["date"])+"\t" +str(archive_monitoring["releves_mesure2"])+"\n"
  22.         fileW2 = open("save1/monitor2.txt", "w")
  23.         fileW2.write(textInsert2 + text2)
  24.         fileW2.close()
  25.  
Expand|Select|Wrap|Line Numbers
  1. def affichage_update ():
  2.     with open('save1/monitor1.txt',"r") as monitor1, open('save1/monitor2.txt',"r") as monitor2:     
  3.         s= Scrollbar(releves)
  4.         T= Text(releves,bg='powder blue',width=450,height=350,font=('arial',14,'bold'),pady=25)   
  5.         s.pack(side=RIGHT, fill=Y)
  6.         T.pack(side=LEFT, fill=Y)
  7.         s.config(command=T.yview)
  8.         T.config(yscrollcommand=s.set)        
  9.         while True:
  10.             line1 = monitor1.readline()
  11.             if len(line1) == 0:
  12.                 break
  13.             line1 = line1.strip().split()
  14.             line2 = monitor2.readline()
  15.             line2 = line2.strip().split()
  16.             T.insert(END, f'{line1[0]:15}\t {line1[1]:10}\t\t {line2[1]:10}\n')
  17.     T.update_idletasks()
  18.     T.after(500,affichage_update)  
  19.  
  20.  
code for notebook and label :

Expand|Select|Wrap|Line Numbers
  1. container=ttk.Notebook(root,width=450,height=350)
  2. monitoring=Frame(container,bg='powder blue')
  3. container.add(monitoring,text='monitor data')
  4. releves=Frame(container,bg='powder blue')
  5. container.add(releves,text='releves')
  6. lbf1 = LabelFrame(monitoring, text="Lecture Monitor 1",padx=10, pady=10)
  7. lbf1.pack(side=LEFT,padx=10, pady=10,anchor=NE)
  8. entry_lbf1= Entry(lbf1,textvariable=ent_releves1)
  9. entry_lbf1.pack(pady=5)
  10. lbf2 = LabelFrame(monitoring, text="Lecture Monitor 2",padx=10, pady=10)
  11. lbf2.pack(side=LEFT,padx=10, pady=10,anchor=NW)
  12. entry_lbf2= Entry(lbf2,textvariable=ent_releves2)
  13. entry_lbf2.pack(pady=5)
  14. bt_archiver=Button(monitoring,text='Archiver',command=archiver)
  15. bt_archiver.place(x=40,y=120)
  16.  
Expand|Select|Wrap|Line Numbers
  1. generalites_top=Frame(releves,bg='powder blue',width=450)
  2. generalites_top.pack(side=TOP,fill=X)
  3. generalites_bottom=Frame(releves,bg='powder blue')
  4. generalites_bottom.pack(side=BOTTOM)
  5. head_axe_loc35L = ['Date', 'Monitor 1', 'Monitor 2']
  6. lb_date=Label(generalites_top,text=f'{head_axe_loc35L[0]:15}',bg='powder blue',font=('arial',12,'bold'))
  7. lb_date.pack(side=LEFT,padx=5,anchor=NW)
  8. lb_monitor1=Label(generalites_top,text=f'{head_axe_loc35L[1]:10}',bg='powder blue',font=('arial',12,'bold'))
  9. lb_monitor1.pack( side=LEFT)
  10. lb_monitor2=Label(generalites_top,text=f'{head_axe_loc35L[2]:10}',bg='powder blue',font=('arial',12,'bold'))
  11. lb_monitor2.pack(padx=70, side=LEFT)
  12.  
Expand|Select|Wrap|Line Numbers
  1. with open('save1/monitor1.txt',"r") as monitor1, open('save1/monitor2.txt',"r") as monitor2:        
  2.     s= Scrollbar(releves)
  3.     T= Text(releves,bg='powder blue',width=450,height=350,font=('arial',14,'bold'),pady=25)
  4.  
  5.     s.pack(side=RIGHT, fill=Y)
  6.     T.pack(side=LEFT, fill=Y)
  7.     s.config(command=T.yview)
  8.     T.config(yscrollcommand=s.set)        
  9.     while True:
  10.         line1 = monitor1.readline()
  11.         if len(line1) == 0:
  12.             break
  13.         line1 = line1.strip().split()
  14.         line2 = monitor2.readline()
  15.         line2 = line2.strip().split()
  16.         T.insert(END, f'{line1[0]:15}\t {line1[1]:10}\t\t {line2[1]:10}\n')
  17. T.update_idletasks()           
  18. T.after(500,affichage_update)  
  19. container.pack(expand=1, fill='both', padx=5, pady=5) 
  20. root.mainloop()
  21.  
I need help to rectify my code
thanks for help
Dec 11 '18 #1
Share this Question
Share on Google+
1 Reply


Expert 100+
P: 621
Most likely the while True is hogging the processor and not letting anything else happen. Instead of a while True, call another function repeatedly, using after() to update the Text and then call itself again. The small amount of time after() waits before executing gives the processor/Tkinter time to do things like update widgets. The same for any other while True loops. Sorry, but there is too much code for me to trudge through (How come you have this problem at this stage. Has this code not been tested at all?). Will try to come up with a simple example later today, but no promises.

Edit: this is code in my toolbox. Note how the countdown timer creates the Label and then updates it through a second function (the simple progressbar has nothing to do with your question). I would also strongly suggest that you learn classes before Tkinter as it solves some problems, like accessing variables in a called function that were created somewhere else.
Expand|Select|Wrap|Line Numbers
  1. class ProgressBar():
  2.     def __init__(self, root):
  3.         self.root=root
  4.         self.root.geometry("75x50+900+100")
  5.         tk.Button(self.root, text="Quit", bg="red", command=self.root.destroy).pack()
  6.         self.ctr=25
  7.         self.start_progress_bar()
  8.         self.start_countdown()
  9.  
  10.     def start_progress_bar(self):
  11.         """ create a simple progress bar widget on a canvas
  12.         """
  13.         self.top=tk.Toplevel(self.root, takefocus=True)
  14.         self.top.title("Progress Bar")
  15.         self.top.geometry("+700+200")
  16.         self.canvas = tk.Canvas(self.top, width=261, height=60, background='lightgray')
  17.         self.canvas.pack()
  18.  
  19.         self.rc1 = self.canvas.create_rectangle(24, 20, 32, 50, outline='white', \
  20.                                       fill='blue')
  21.         self.start_x=20
  22.         self.end_x=235
  23.         self.this_x=self.start_x
  24.         self.one_25th = (self.end_x-self.start_x)/25.0
  25.         rc2 = self.canvas.create_rectangle(self.start_x, 20, self.end_x, 50,
  26.                                        outline='blue', fill='lightblue')
  27.         self.rc1 = self.canvas.create_rectangle(self.start_x, 20, self.start_x+7, 50,
  28.                                        outline='white', fill='blue')
  29.  
  30.         self.update_scale()
  31.  
  32.     def start_countdown(self):
  33.         """ a separate process in a separate GUI
  34.         """
  35.         top2=tk.Toplevel(self.root, bg="lightyellow")
  36.         top2.geometry("50x25")
  37.         self.label_ctr = tk.IntVar()
  38.         self.label_ctr.set(self.ctr)
  39.         tk.Label(top2, textvariable=self.label_ctr, width=10,
  40.                  font=("Verdans", 15)).pack()
  41.         if self.ctr > 0:
  42.             self.update()
  43.         else:
  44.             self.top2.destroy()
  45.  
  46.     def update(self):
  47.         if self.ctr > 0:
  48.             self.label_ctr.set(self.ctr)
  49.             self.ctr -= 1
  50.             self.root.after(750, self.update)
  51.         else:
  52.             ## sleep for one second to allow any remaining after() to execute
  53.             ## can also use self.root.after_cancel(id)
  54.             self.root.after(1000, self.root.destroy)
  55.  
  56.     def update_scale(self):
  57.         self.canvas.move(self.rc1, self.one_25th, 0)
  58.         self.canvas.update()
  59.         self.this_x += self.one_25th
  60.         ## reverse direction at either end
  61.         if (self.this_x >= self.end_x-12) or self.this_x <= self.start_x+7:
  62.             self.one_25th *= -1
  63.  
  64.         ## only call after() while the countdown is running (self.ctr > 0)
  65.         ## to avoid a dangling after() when the program terminates
  66.         if self.ctr > 0:
  67.             self.canvas.after(200, self.update_scale)
  68.  
  69. root = tk.Tk()
  70.  
  71. PB=ProgressBar(root)
  72. root.mainloop() 
Dec 12 '18 #2

Post your reply

Sign in to post your reply or Sign up for a free account.