Threads et threading

Bonjour,

mon problème :
j’ai un label sur ma frame
j’ai une boucle pour trier des caractères (ça c’est ok) la boucle est dans une fonction.
je souhaite afficher un compteur d’exécution pour donner une info de fonctionnement du code dans ce label.
j’utilise la commande label.config(text= dans mon cas un entier), j’ai essayé avec la commande label.configure(xxx,xx) , mais mis dans ma boucle. ça ne change pas la valeur du label.
j’ai mis ces commande avec un sleep(xx) qui ne donne rien de plus, j’ai mis la commande dans une fonction idem. j’ai mis la fonction dans un thread, pas mieux…
En mode debug, je peux suivre le fonctionnement et le code « saute » ma commande label.config() et par contre imprime la commande dans le debug. je suppose qu’il manque qqchose pour faire le changement.
Le label se met à jour en fin de boucle pour la dernière valeur mais ne s’incrémente pas (ou décrément pas dans mon cas.)

Je râte qqchose bien sûr car les essais avec les bouts de code en dehors de mon appli fonctionnent.

Une piste?
Je suis preneur, d’avance merci.

jym

1 « J'aime »

Pouvez-vous nous montrer votre code source, pour qu’on puisse voir d’où vient le problème ?

Essayez de mettre à jour l’objet window et le label après avoir modifié le texte du label :

root = tkinter.Tk()
mylabel = tkinter.Label(root, text=xxxxxxx', font=FONT)
#.....
#.....
#.....
root.update()        # <- mettre à jour le window
mylabel.update()     # <- mettre à jour le label 

En fait, il n’est pas recommandé de mettre à jour le label tkinter dans un thread.

bonjour et merci de vous pencher sur mon pbm…
le code de la fonction appelante

def pdf_ou_txt():
    global nom_base_archives  # contiendra le nom de la base
    global chemin_base_archives  # contiendra le chemin de la base
    global chaine_base  # contiendra lechemin et le nom de la base données
    global repertoire_a_scanner
    global index_repertoire_en_scan
    global ma_chaine
    test=("")  #variable de stockage des mots pourl'enregistrement après la lecture d 'un document
    global text_lab_2
    global mon_compte




    # AFFICHE DLG BOX POUR AJOUTER les mots du pdf a la base
    MsgBox = tk.messagebox.askquestion('Quel type de fichier? PDF = OUI, TXT = NON', 'PDF', icon='warning')

    label2.config(text='ligne 295 dans pdf ou txt pdf_ou_txt')

    if MsgBox == 'yes':  #traitement des pdf
        # https://python.doctor/page-gestion-fichiers-dossiers-python
        # zone avec globe mais affiche le chemin ET le nom
        #path_to_target = "C:\\RADIO\\PYTHON PROGRAMME\\ESSAIS DE CODES\\essai de compate des mots dans pdf\\"

        path_to_file_list = glob.glob(repertoire_a_scanner + '*pdf')

        ma_chaine = ""
        #label2.config(text='ligne 309 dans pdf ou txt')

        for path_to_file in path_to_file_list:
           #traiter ici la gestion des mots depuis ma_chaine avant d elui donner une autre valeur
            if len(ma_chaine) > 0:
                ma_chaine=""

            ma_chaine = path_to_file.rsplit('\\', maxsplit=1)
            avant = ma_chaine[0]  # le chemin
            apres = ma_chaine[1]  # le fichier

            ma_chaine=""
            # a partir d'ici faire une boucle pour traiter tous les fichiers .pdf du répertoire=====================================
            #for file in
            #global traiter_txt ="faire_txt""
            #path_to_file="D:\REPERTOIRE PDF\\pdf1.pdf"



            # creating a pdf file object
            pdfFileObj = open(path_to_file,'rb')  #essai avec le dernier fichier traité dans le run ci dessus
            # creating a pdf reader object
            pdfReader = PyPDF2.PdfFileReader(pdfFileObj)



            # creating a page object
            pageObj = pdfReader.getPage(0)  # pour ne charger que la prmeière page
            global mon_compte
            mon_compte = len(pageObj.extractText())
            print ('mon compte vaut : ', mon_compte)
            threads = []




            # extracting text from page
            for caractere in pageObj.extractText():
                t = threading.Thread(target=fun1(mon_compte), daemon=True)
                threads.append(t)
                t.start()
                # mets à jour la labe2 c'est fini
                #label3.config(text=mon_compte)  # + str(y))

                t.join()


                #sleep(1)
                y = ord(caractere)   #trouve la valeur ascii du caractère
                L = len(pageObj.extractText())
                if y in range(33, 47):  #minuscules
                    ma_chaine = ma_chaine + str(caractere)

                if y in range(48, 127):  #majuscles
                    ma_chaine = ma_chaine + str(caractere)

                if y ==183:  #le point
                    ma_chaine = ma_chaine + str(caractere)

                if y in range(224,227): #les a accentués
                    if y==224:
                        ma_chaine = ma_chaine + str(caractere) +'\n'  #ajoute le à la chaine
                        #y=32  #pour construire une séparation qui se fera en bas des cas avec 32 et 47

                    else :
                        ma_chaine = ma_chaine + str(caractere)

                if y in range(231,236):
                    ma_chaine = ma_chaine + str(caractere)

                if y in range (242,253) :
                    ma_chaine = ma_chaine + str(caractere)

                if y == 32 or y == 47 or y==10: #"espace ou le slash"  ou LF
                    # ma_chaine= ma_chaine+chr(10),chr(13)
                    # if y==47:
                    # rempli la liste test pour l'enregistrer en 1 fois
                    ma_chaine = (ma_chaine +'\n' )
                    test=test +(ma_chaine)  #contient la liste de mots avec un cr à chaque fois de séparation
                    ma_chaine=""  #vide la chaine
                    # print('test = ',test)
                    # print('le type de test est :', type(test))



                mon_compte=mon_compte-1
            # mets à jour la labe2   c'est fini
            label2.config(text='Find du traitement avant ')
            #mon_compte=mon_compte+1




            # retire les doublons de la liste
            #print('longeur de test avant la compression', len(test))
            test = test+(ma_chaine)+"\n"
            ma_liste = list(OrderedDict.fromkeys(test))

            #print('longeur ma liste apres compression', len(ma_liste))
            # effectue l'enregistrement dans le fichier text
            #y = len(ma_liste)
            fichier = open(avant+'\\'+"data.txt", "w")  #ouvre le fichier data dans le rep de la base
            #ma_chaine = "\n"
            #fichier.write(ma_chaine)
            for w in test:
                fichier.write(w)
            fichier.close()

            #enregistrement des mots dans la table des mots
            ma_chaine = ""  #à modifier
            # print(ma_chaine)

            # closing the pdf file objectle
            pdfFileObj.close()
            #print ('fin')
            # mets à jour la labe2   c'est fini
            label2.config(text='Find du traitement')

    else :
    #traite les txt
        print()

le code de la thread elle mm

def fun1(a):
    print()

    global mon_compte

    label3.config(text=mon_compte)
    sleep(1)
    print('mon_compte vaut dans thread: ',mon_compte)

========================
ça n’est pas une oeuvre d’art, et pour l’instant c’est un peu en vrac car je suis en mode debug.

ce code ne change pas la valeur de label3 alors qu’on passe dessus (thread ou pas thread du reste;

le résultat final demandé pour l’instant (la copie des mots dans un fichier text) fonctionne. A terme ça sera une chaine et je travaille dessus pour l 'enregistrer dans une base (qui existe et qui fonctionne).

Toute info est bien venue.
Bonne journée.
jym

Bonjour Jacques,
je vais essayer ça.
je vous dis le résultat.
merci

Bonjour Henri,

merci de votre info.
vous pouvez donner une explication?
bonne journée.
jym

Qu’affiche cette ligne ?

Essayez de remplacer cette ligne

Par celle-ci:

label3.config(text = "Hello World", width = "50")

Pour voir si label3 va changer. Parce qu’on sait pas si la valeur de mon_compte est mis à jour ou non.

Re bonjour Jacques, toujours de bon conseil.
Simple et efficace, ça suffit à mon bonheur.
J’ai mis le label update dans ma thread. nickel

je n’ai pas testé root.update pour l’instant, peut être pas utile de rafraichir toute la frame à chaque fois (plusieurs milliers de passages dans la boucle) Je scanne des pdf pour en récupérer les caractères/mots. 1 page de pdf ça fait environ 2000 caractères.

en tout cas ça fonctionne.

j’ai du mal à trouver toutes les fonctions des objets. il y a la liste qui s’affiche quand on code (pycharm ici) mais celle là j’aurai pu la trouver…
Merci de votre aide.
Surement à une prochaine fois. HI!
jym

re bonjour Isaac,
oui c’est mis à jour, le print met la bonne valeur dans le debug.

Jacques m’a donné une bonne piste avec la fonction.update(); ça marche et ça met à jour en continu mon compteur dans label3.
jym

2 « J'aime »