Fermer une fenêtre Tk en cours de process
Diablo76 Messages postés 213 Date d'inscription vendredi 25 novembre 2022 Statut Membre Dernière intervention 15 février 2025 - 1 mai 2024 à 16:20
- La ressource demandée est en cours d'utilisation
- Notice d'utilisation - Guide
- Utilisation chromecast - Guide
- Imprimante en cours d'utilisation - Forum Imprimante
- En cours de livraison - Forum Consommation & Internet
- Il est en cours de transport vers votre site de livraison - Forum Consommation & Internet
7 réponses
30 avril 2024 à 13:48
Salut Phil,
Je ne sais si ça va correspondre à tes besoins, mais avec la méthode update() et un bind sur la croix de la fenêtre, je verrai qq chose comme ça :
import tkinter as tk flag = True def loop(): i = 0 while flag: i+=1 print(f"Loop n° {i}") root.update() print("Loop off") def on_exit(): global flag flag = False root.destroy() root = tk.Tk() but_search = tk.Button(root, text="Search", command=loop) but_search.pack() but_quit = tk.Button(root, text="Quit", command=on_exit) but_quit.pack() root.protocol('WM_DELETE_WINDOW', on_exit) root.mainloop()
30 avril 2024 à 14:32
bonjour,
ceci donne un message d'erreur quand tu fermes la fenêtre?
import tkinter racine = tkinter.Tk() label = tkinter.Label(racine, text="J'adore Python !") label.pack() racine.mainloop() print("fini")
Salut.
En effet, tkinter ou n'importe quel GUI ne pourra se fermer si on ne lui redonne pas la main.
Donc, ce n'est pas dans tkinter que ce trouve la solution mais dans ta méthode de recherche qui me semble bloquante. Comment grosso-modo est-elle effectuée ?
Ne pourrais-tu pas mettre cela dans un thread ?
Du style (en très gros résumé) :
import tkinter import threading class Search(threading.Thread): def __init__(self, text): super().__init__() self._text = text self._stopped = threading.Event() def run(self): # simulation de qqchose qui prend du temps import time while not self._stopped.is_set(): self._text.insert(tkinter.END, f'{round(time.time())}\n') time.sleep(2) def stop(self): self._stopped.set() def wait_done(ms, window, search): if search.is_alive(): print('waiting...') window.after(ms, wait_done, ms, window, search) else: window.destroy() def on_close(window, search): search.stop() wait_done(100, window, search) def search_run(search, text, button): button.destroy() search.start() window = tkinter.Tk() text = tkinter.Text(window) text.grid() search = Search(text) button = tkinter.Button(window, text='rechercher') button.grid() button.configure(command=lambda: search_run(search, text, button)) window.protocol('WM_DELETE_WINDOW', lambda: on_close(window, search)) window.mainloop()
?
1 mai 2024 à 11:52
N'est-il pas suffisant d'appeller régulièrement la méthode update() de tkinter?
Merci à tous,
Les codes de Diablo et yg_be fonctionnent
Comment ma méthode de recherche est effectuée ?
C'est une double boucle pour comparer 2 listes élément par élément,
le nombre de combinaisons peut être très grand
Le code:
# -*- coding:Utf-8 -*- # 19/04/2024 13:25:08 import itertools as it from tkinter import * def show_result(evt): words_list = [] t1.delete(0.0, END) # Builds anagrams list anag_list = set("".join(e) for e in it.permutations(e1.get(), len(e1.get()))) main_win.update() # Search for el in anag_list: for word in dico: if(el == word): words_list.append(word) if(words_list != []): for el in words_list: t1.insert(END, el+'\n') else: t1.insert(END, 'Rien') def on_exit(): main_win.destroy() WIDTH, HEIGHT = 320, 200 # Makes a list from the dictionnary file dico = [] with open('dico.txt', 'r') as f: for line in f: dico.append(line[:-1]) main_win = Tk() main_win.title('Décoder une anagramme') main_win.geometry(str(WIDTH)+'x'+str(HEIGHT)+'+400+100') main_win.protocol('WM_DELETE_WINDOW', on_exit) l1 = Label(main_win, text='Anagramme :') l1.place(x = 10,y = 20) e1 = Entry(main_win, width = 10) e1.place(x = 100,y = 20) e1.bind("<Return>", show_result) e1.focus() t1 = Text(main_win, width = 30, height = 7) t1.place(x = 10, y = 50) main_win.mainloop()
dico.txt contient 125623 mots
un mot de 6 lettres a 720 anagrammes
1 mai 2024 à 12:31
je suggère ainsi:
for el in anag_list: main_win.update() if el in dico: words_list.append(el)
1 mai 2024 à 13:06
Il n'est pas nécessaire d'ainsi comparer tous les couples d'éléments des deux listes. Il est préférable de trier les deux listes, puis de les parcourir ensemble, afin d'y trouver les éléments communs.
import itertools as it from tkinter import * def show_result(evt): words_list = [] t1.delete(0.0, END) # Builds anagrams list anag_list = list("".join(e) for e in it.permutations(e1.get(), len(e1.get()))) anag_list.sort() main_win.update() # Search ll1,ll2=len(anag_list),len(dico) i1,i2=0,0 while i1<ll1 and i2<ll2: x1,x2=anag_list[i1],dico[i2] if x1>x2: i2 += 1 elif x1<x2: i1 += 1 else: words_list.append(x1) i1 += 1 i2 += 1 if(words_list != []): for el in words_list: t1.insert(END, el+'\n') else: t1.insert(END, 'Rien') def on_exit(): main_win.destroy() WIDTH, HEIGHT = 320, 200 # Makes a list from the dictionnary file dico = [] with open('dico.txt', 'r') as f: for line in f: dico.append(line[:-1]) dico.sort() main_win = Tk() main_win.title('Décoder une anagramme') main_win.geometry(str(WIDTH)+'x'+str(HEIGHT)+'+400+100') main_win.protocol('WM_DELETE_WINDOW', on_exit) l1 = Label(main_win, text='Anagramme :') l1.place(x = 10,y = 20) e1 = Entry(main_win, width = 10) e1.place(x = 100,y = 20) e1.bind("<Return>", show_result) e1.focus() t1 = Text(main_win, width = 30, height = 7) t1.place(x = 10, y = 50) main_win.mainloop()
1 mai 2024 à 13:25
Cela permet de comparer seulement une ou deux fois chaque mot du dico, plutôt que de comparer chaque mot à chaque anagramme possible.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionBonjour yg_be,
C'est bien ça: j'ai fait le test avant d'avoir lu ta réponse, mais après avoir lu
celle de 11h52
Ca fonctionne bien
Merci encore à tous, problème résolu !
1 mai 2024 à 13:09
Tu auras vu aussi qu'il est préférable d'utiliser "if ... in ..." plutôt que faire une boucle.
Modifié le 1 mai 2024 à 14:14
Je pense que l'on peut aussi optimiser le code en créant un dictionnaire à partir de la liste de mots ayant pour clé la longeur et de créer ana_set au fur et à mesure de l'itération pour contrôler les boublons:
import itertools as it from tkinter import * def show_result(evt): t1.delete(0.0, END) it_perm = it.permutations(e1.get()) anag_set = set() for perm in it_perm: word = "".join(perm) if not len(word) in dico.keys(): break if word in dico[len(word)] and word not in anag_set: t1.insert(END, word+"\n") anag_set.add(word) if not anag_set: t1.insert(END, 'Rien') def on_exit(): main_win.destroy() WIDTH, HEIGHT = 320, 200 dico = {} with open('dico.txt', 'r') as f: for line in f: line = line.strip() longueur_mot = len(line) if longueur_mot not in dico: dico[longueur_mot] = [line] else: dico[longueur_mot].append(line) main_win = Tk() main_win.title('Décoder une anagramme') main_win.geometry(f"{WIDTH}x{HEIGHT}+400+100") main_win.protocol('WM_DELETE_WINDOW', on_exit) l1 = Label(main_win, text='Anagramme :') l1.place(x=10, y=20) e1 = Entry(main_win, width=10) e1.place(x=100, y=20) e1.bind("<Return>", show_result) e1.focus() t1 = Text(main_win, width=30, height=7) t1.place(x=10, y=50) main_win.mainloop()
je pense que ça peut être encore optimiser
1 mai 2024 à 14:28
Toutes les permutation ayant la même longueur:
def show_result(evt): t1.delete(0.0, END) it_perm = it.permutations(e1.get()) lenw=len(e1.get()) anag_set = set() if lenw in dico.keys(): dicol=dico[lenw] for perm in it_perm: word = "".join(perm) if word in dicol: t1.insert(END, word+"\n") anag_set.add(word) if not anag_set: t1.insert(END, 'Rien')
Modifié le 1 mai 2024 à 14:59
Tu ne tiens pas compte des doublons générés par it.permutations() pour l'affichage, autrement anag_set ne sert pas à grand-chose.
1 mai 2024 à 16:11
Pourquoi tester si chacun des doublons est dans le dico?
Mieux de les éliminer dès le départ:
it_perm = set(it.permutations(e1.get()))
J'ai fini par faire ceci, et ça marche pas mal:
# -*- coding:Utf-8 -*- # 19/04/2024 13:25:08 import itertools as it from time import perf_counter from tkinter import * def time_format(_time): units = 's' if(_time > 60.0): _time, units = _time/60.0, 'mn' return(_time,units) def show_result(evt): # Makes a list from the dictionnary file dico = [] with open('dico.txt', 'r') as f: for line in f: if(len(line[:-1]) == len(e1.get())): dico.append(line[:-1]) words_list = [] t1.delete(0.0, END) l3['text'] = 'Temps passé : ' # Builds anagrams list avoiding doubles anag_list = set("".join(e) for e in it.permutations(e1.get(), len(e1.get()))) estimated_t, units = time_format((len(anag_list) * len(dico))/LOOPS_PER_SECOND) l2['text'] = 'Temps estimé : {:.2f} {}'.format(estimated_t, units) # Search t1.configure(cursor = 'wait') start = perf_counter() for el in anag_list: main_win.update() if(el in dico): t1.insert(END, el+'\n') end = perf_counter() t1.configure(cursor = '') elapsed_t, units = time_format(end-start) l3['text'] = f'Temps passé: {elapsed_t: 0.2f} {units} ' def on_exit(): main_win.destroy() LOOPS_PER_SECOND = 16056487 VOWELS = 'aeiouy' WIDTH, HEIGHT = 320, 200 main_win = Tk() main_win.title('Décoder une anagramme') main_win.geometry(str(WIDTH)+'x'+str(HEIGHT)+'+400+100') main_win.protocol('WM_DELETE_WINDOW', on_exit) l1 = Label(main_win, text='Anagramme :') l1.place(x = 10,y = 20) e1 = Entry(main_win, width = 10) e1.place(x = 100,y = 20) e1.bind("<Return>", show_result) e1.focus() l2 = Label(main_win, text='Temps estimé :') l2.place(x = 170,y = 20) t1 = Text(main_win, width = 30, height = 7) t1.place(x = 10, y = 50) l3 = Label(main_win, text='Temps passé :') l3.place(x = 10,y = 170) main_win.mainloop()
1 mai 2024 à 15:32
Chez moi ça ne marche pas.
Traceback :
Traceback (most recent call last): File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__ return self.func(*args) File "/home/diablo76/Bureau/Test_Python/pythonTest/bon.py", line 39, in show_result t1.configure(cursor = 'wait') File "/usr/lib/python3.10/tkinter/__init__.py", line 1675, in configure return self._configure('configure', cnf, kw) File "/usr/lib/python3.10/tkinter/__init__.py", line 1665, in _configure self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) _tkinter.TclError: bad cursor spec "wait"
1 mai 2024 à 16:14
dommage de relire ainsi le fichier à chaque fois.
1 mai 2024 à 16:20
Absolument d'accord et avec mes mixt's que l'on t'a fait , tu as une solution