Forum Programmation.python actualisation automatique le contenu du widget Text dans tkinter

Posté par  . Licence CC By‑SA.
Étiquettes :
3
26
nov.
2018

bonjour;
je suis entrain de finaliser un projet, et j'ai rencontre un problème concernant l'actualisation automatique (update) du contenu du widget tkinter Text . voci le code correspondant à la partie qui pose problème :

    from tkinter import *
    from tkinter.ttk import Notebook
    import tkinter.ttk as ttk
    import time

    #window
    root=Tk()
    root.geometry('450x350')
    root.title('test')

    #variables
    ent_releves1=StringVar()
    ent_releves2=StringVar()

    #Functions:
    def archiver():

        archive_monitoring={"date" : time.strftime('%d/%m/%y', time.localtime()),   
                      "releves_mesure1": ent_releves1.get(),
                      "releves_mesure2": ent_releves2.get(),                          } 

        if (ent_releves1.get() !="" ) : 
            mon_fichier1 = open("save/monitor1.txt", "r")
            text1 = mon_fichier1.read()
            mon_fichier1.close()                        
            textInsert1=str(archive_monitoring["date"])+"\t" +str(archive_monitoring["releves_mesure1"])+"\n"
            fileW1 = open("save/monitor1.txt", "w")
            fileW1.write(textInsert1 + text1)
            fileW1.close()

        if (ent_releves2.get() !="" ) : 
            mon_fichier2 = open("save/monitor2.txt", "r")
            text2 = mon_fichier2.read()
            mon_fichier2.close()                        
            textInsert2=str(archive_monitoring["date"])+"\t" +str(archive_monitoring["releves_mesure2"])+"\n"
            fileW2 = open("save/monitor2.txt", "w")
            fileW2.write(textInsert2 + text2)
            fileW2.close()

    def affichage_update ():

        with open('save/monitor1.txt',"r") as monitor1, open('save/monitor2.txt',"r") as monitor2:

            s= Scrollbar(releves)
            T= Text(releves,bg='powder blue',width=450,height=350,font=('arial',14,'bold'),pady=25)

            s.pack(side=RIGHT, fill=Y)
            T.pack(side=LEFT, fill=Y)
            s.config(command=T.yview)
            T.config(yscrollcommand=s.set)

            while True:
                line1 = monitor1.readline()
                if len(line1) == 0:
                    break
                line1 = line1.strip().split()
                line2 = monitor2.readline()
                line2 = line2.strip().split()
                T.insert(END, f'{line1[0]:15}\t {line1[1]:10}\t\t {line2[1]:10}\n')
        T.update_idletasks()


        T.after(500,affichage_update)   


    container=ttk.Notebook(root,width=450,height=350)

    monitoring=Frame(container,bg='powder blue')
    container.add(monitoring,text='monitor data')

    releves=Frame(container,bg='powder blue')
    container.add(releves,text='releves')

    lbf1 = LabelFrame(monitoring, text="Lecture Monitor 1",padx=10, pady=10)
    lbf1.pack(side=LEFT,padx=10, pady=10,anchor=NE)

    entry_lbf1= Entry(lbf1,textvariable=ent_releves1)
    entry_lbf1.pack(pady=5)

    lbf2 = LabelFrame(monitoring, text="Lecture Monitor 2",padx=10, pady=10)
    lbf2.pack(side=LEFT,padx=10, pady=10,anchor=NW)

    entry_lbf2= Entry(lbf2,textvariable=ent_releves2)
    entry_lbf2.pack(pady=5)


    bt_archiver=Button(monitoring,text='Archiver',command=archiver)
    bt_archiver.place(x=40,y=120)


    generalites_top=Frame(releves,bg='powder blue',width=450)
    generalites_top.pack(side=TOP,fill=X)

    generalites_bottom=Frame(releves,bg='powder blue')
    generalites_bottom.pack(side=BOTTOM)

    head_axe_loc35L = ['Date', 'Monitor 1', 'Monitor 2']

    lb_date=Label(generalites_top,text=f'{head_axe_loc35L[0]:15}',bg='powder blue',font=('arial',12,'bold'))
    lb_date.pack(side=LEFT,padx=5,anchor=NW)

    lb_monitor1=Label(generalites_top,text=f'{head_axe_loc35L[1]:10}',bg='powder blue',font=('arial',12,'bold'))
    lb_monitor1.pack( side=LEFT)

    lb_monitor2=Label(generalites_top,text=f'{head_axe_loc35L[2]:10}',bg='powder blue',font=('arial',12,'bold'))
    lb_monitor2.pack(padx=70, side=LEFT)


    with open('save/monitor1.txt',"r") as monitor1, open('save/monitor2.txt',"r") as monitor2:

        s= Scrollbar(releves)
        T= Text(releves,bg='powder blue',width=450,height=350,font=('arial',14,'bold'),pady=25)

        s.pack(side=RIGHT, fill=Y)
        T.pack(side=LEFT, fill=Y)
        s.config(command=T.yview)
        T.config(yscrollcommand=s.set)

        while True:
            line1 = monitor1.readline()
            if len(line1) == 0:
                break
            line1 = line1.strip().split()
            line2 = monitor2.readline()
            line2 = line2.strip().split()
            T.insert(END, f'{line1[0]:15}\t {line1[1]:10}\t\t {line2[1]:10}\n')

    T.update_idletasks()

    T.after(500,affichage_update)   

    container.pack(expand=1, fill='both', padx=5, pady=5)


    root.mainloop()
  • # Un peu d'améliorations

    Posté par  . Évalué à 4. Dernière modification le 26/11/18 à 12:17.

    Comme tu es en train de finaliser ton projet avec entrain :) , j'ajoute un commentaire.

    Je ne trouve pas cela être une bonne idée d'avoir plusieurs fichiers pour les monitors, un simple fichier par exemple un csv serait plus adapté, car en l'état si on n'enregistre qu'une seule des deux valeurs, on se retrouvera décalé dans l'affichage et aucun moyen de faire de distinctions, car il y a seulement une date.

    Dans ta fonction affichage_update, tu crées de nouveau widgets, ce qui n'a pas intérêt.

    Pour la mise à jour de l'affichage, tu peux le faire soit avec l'event associé au notebook, soit en temps réel lors de chaque archivage de valeurs.

    Ayant du temps à perdre, voici un exemple fonctionnel (désolé, j'ai modifié l’import *).

    import tkinter as tk
    import tkinter.ttk as ttk
    import csv
    import time
    
    RELEVES_FILE = './save/releves.csv'
    RELEVES_FRAME_NAME = 'releves'
    
    #window
    root = tk.Tk()
    root.geometry('450x350')
    root.title('test')
    
    
    def date():
        return time.strftime('%d/%m/%y', time.localtime())
    
    
    def archiver(entry1, entry2):
        mesures = [None, entry1.get().strip(), entry2.get().strip()]
        if not any(mesures):
            return
        mesures[0] = date()
    
        with open(RELEVES_FILE, 'a', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(mesures)
    
        entry1.delete(0, tk.END)
        entry2.delete(0, tk.END)
    
    
    def affichage_update(notebook, wtext):
        frame_name = notebook.select()
        if not RELEVES_FRAME_NAME in frame_name:
            return
        wtext['state'] = tk.NORMAL
        wtext.delete(0.0, tk.END)
        with open(RELEVES_FILE, 'r', newline='') as f:
            reader = csv.reader(f)
            for row in reader:
                text = f'{row[0]:15}\t {row[1]:10}\t\t {row[2]:10}\n'
                wtext.insert(tk.END, text)
        wtext['state'] = tk.DISABLED
    
    
    container = ttk.Notebook(root,width=450, height=350)
    container.pack(expand=1, fill='both', padx=5, pady=5)
    
    monitoring = tk.Frame(container, bg='powder blue')
    container.add(monitoring, text='monitor data')
    
    releves = tk.Frame(container, bg='powder blue', name=RELEVES_FRAME_NAME)
    container.add(releves,text='releves')
    
    lbf1 = tk.LabelFrame(monitoring, text="Lecture Monitor 1", padx=10, pady=10)
    lbf1.pack(side=tk.LEFT, padx=10, pady=10, anchor=tk.NE)
    
    entry_lbf1 = tk.Entry(lbf1)
    entry_lbf1.pack(pady=5)
    
    lbf2 = tk.LabelFrame(monitoring, text="Lecture Monitor 2", padx=10, pady=10)
    lbf2.pack(side=tk.LEFT, padx=10, pady=10, anchor=tk.NW)
    
    entry_lbf2 = tk.Entry(lbf2)
    entry_lbf2.pack(pady=5)
    
    
    bt_archiver = tk.Button(monitoring,text='Archiver', command=lambda : archiver(entry_lbf1, entry_lbf2))
    bt_archiver.place(x=40,y=120)
    
    
    generalites_top = tk.Frame(releves, bg='powder blue', width=450)
    generalites_top.pack(side=tk.TOP, fill=tk.X)
    
    generalites_bottom = tk.Frame(releves,bg='powder blue')
    generalites_bottom.pack(side=tk.BOTTOM)
    
    head_axe_loc35L = ['Date', 'Monitor 1', 'Monitor 2']
    
    lb_date = tk.Label(generalites_top, text=f'{head_axe_loc35L[0]:15}', bg='powder blue', font=('arial',12,'bold'))
    lb_date.pack(side=tk.LEFT, padx=5, anchor=tk.NW)
    
    lb_monitor1 = tk.Label(generalites_top, text=f'{head_axe_loc35L[1]:10}', bg='powder blue', font=('arial',12,'bold'))
    lb_monitor1.pack(side=tk.LEFT)
    
    lb_monitor2 = tk.Label(generalites_top, text=f'{head_axe_loc35L[2]:10}', bg='powder blue', font=('arial',12,'bold'))
    lb_monitor2.pack(padx=70, side=tk.LEFT)
    
    
    s = tk.Scrollbar(releves)
    T = tk.Text(releves, bg='powder blue', width=450, height=350, font=('arial',14,'bold'), pady=25, state=tk.DISABLED)
    
    s.pack(side=tk.RIGHT, fill=tk.Y)
    T.pack(side=tk.LEFT, fill=tk.Y)
    s.config(command=T.yview)
    T.config(yscrollcommand=s.set)
    
    container.bind('<<NotebookTabChanged>>', lambda evt: affichage_update(container, T))
    
    root.mainloop()

    Pour l'affichage, au lieu d'aller chaque fois relire le fichier, tu pourrais optimiser cela en gardant les valeurs en cache que tu actualiserais à chaque archivage.

    • [^] # Re: Un peu d'améliorations

      Posté par  . Évalué à 2.

      bonsoir;
      merci pour le code qui est bien formule et qui marche bien.
      le bout de code que j'ai indique auparavant est une partie de l'application totale de presque 4900 lignes actuellement
      pour l'archivage sur deux fichiers différents mais avec des valeurs qui peuvent être égales ou distinctes correspondant a l’état équipement électronique surveille par deux monitors.
      en plus du fait que chaque fichier est représenté par un graphe grâce a la bibliothèque matplotlib
      ceci dit: serait il possible de me dire ou se trouve la faute de programmation dans mon code

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.