Je poste ceci parce que j'ai moi-même eu du mal à trouver une réponse claire à ce problème. . .Désactiver la sortie (ou [X]) dans la fenêtre tkinter
En cherchant à essayer de créer une barre de progression pour mon programme, je trouve qu'il est difficile de faire avec tkinter. Pour accomplir la création d'une barre de progression sans courir dans le "mainloop" redouté, I opted to make a class out of the progress bar using threads. A travers beaucoup d'essais une erreur, j'ai trouvé qu'il n'y a pas grand chose qui peut être personnalisé en raison de l'utilisation du multithreading (tkinter aime être dans le thread principal). Voici deux options que j'ai essayé, suivi d'un troisième qui correspond le mieux à mes besoins:
Option 1: En utilisant une fonction de rappel
Vu le code suivant:
import tkinter as tk
import tkinter.ttk as ttk
import threading
class ProgressbarApp(threading.Thread):
def __init__(self, max_value: int):
self.max_value = max_value
self.root = None
self.pb = None
threading.Thread.__init__(self)
self.lock = threading.Lock() # (1)
self.lock.acquire() # (2)
self.start()
# (1) Makes sure progressbar is fully loaded before executing anything
with self.lock:
return
def close(self):
self.root.quit()
def run(self):
self.root = tk.Tk()
self.root.protocol("WM_DELETE_WINDOW", self.__callback)
self.pb = ttk.Progressbar(self.root, orient='horizontal', length=400, mode='determinate')
self.pb['value'] = 0
self.pb['maximum'] = self.max_value
self.pb.pack()
self.lock.release() # (2) Will release lock when finished
self.root.mainloop()
def update(self, value: int):
self.pb['value'] = value
@staticmethod
def __callback():
return
if __name__ == '__main__':
interval = 100000
my_pb = ProgressbarApp(interval)
for i in range(interval):
my_pb.update(i)
my_pb.close()
# Other stuff goes on . . .
Où
self.root.protocol("WM_DELETE_WINDOW", self.__callback)
Empêche la fermeture de la fenêtre. Cependant, si le bouton Quitter ou [X] devait être maintenu enfoncé, la barre de progression se bloquerait jusqu'à ce que l'utilisateur relâche le bouton. (La fonction __callback est constamment appelée, empêchant d'autres tâches d'être complétées).
Option 2: Utilisation root.overriderdirect (Vrai)
Vu le code suivant:
import tkinter as tk
import tkinter.ttk as ttk
import threading
class ProgressbarApp(threading.Thread):
def __init__(self, max_value: int):
self.max_value = max_value
self.root = None
self.pb = None
threading.Thread.__init__(self)
self.lock = threading.Lock() # (1)
self.lock.acquire() # (2)
self.start()
# (1) Makes sure progressbar is fully loaded before executing anything
with self.lock:
return
def close(self):
self.root.quit()
def run(self):
self.root = tk.Tk()
self.root.overrideredirect(True)
self.pb = ttk.Progressbar(self.root, orient='horizontal', length=400, mode='determinate')
self.pb['value'] = 0
self.pb['maximum'] = self.max_value
self.pb.pack()
self.lock.release() # (2) Will release lock when finished
self.root.mainloop()
def update(self, value: int):
self.pb['value'] = value
if __name__ == '__main__':
interval = 100000
my_pb = ProgressbarApp(interval)
for i in range(interval):
my_pb.update(i)
my_pb.close()
# Other stuff goes on . . .
Où
self.root.overrideredirect(True)
efface toutes tkinters options de la fenêtre. Cependant, la barre de progression n'est pas seulement dans un emplacement impair, mais elle masque également la fenêtre des utilisateurs. La barre de progression devrait être conviviale.
Option 3: Utilisation root.attributes ('- désactivé', true)
Vu le code suivant:
import tkinter as tk
import tkinter.ttk as ttk
import threading
class ProgressbarApp(threading.Thread):
def __init__(self, max_value: int):
self.max_value = max_value
self.root = None
self.pb = None
threading.Thread.__init__(self)
self.lock = threading.Lock() # (1)
self.lock.acquire() # (2)
self.start()
# (1) Makes sure progressbar is fully loaded before executing anything
with self.lock:
return
def close(self):
self.root.quit()
def run(self):
self.root = tk.Tk()
self.root.attributes('-disabled', True)
self.pb = ttk.Progressbar(self.root, orient='horizontal', length=400, mode='determinate')
self.pb['value'] = 0
self.pb['maximum'] = self.max_value
self.pb.pack()
self.lock.release() # (2) Will release lock when finished
self.root.mainloop()
def update(self, value: int):
self.pb['value'] = value
if __name__ == '__main__':
interval = 100000
my_pb = ProgressbarApp(interval)
for i in range(interval):
my_pb.update(i)
my_pb.close()
# Other stuff goes on . . .
Où
self.root.attributes('-disabled', True)
empêche toute interaction de l'utilisateur avec la fenêtre . Cela a mieux adapté mes besoins pour ce programme car il empêche la fermeture de la fenêtre et a toujours une belle apparence. (Mon seul problème mineur est que l'utilisateur ne peut plus réduire la barre de progression ou la déplacer).
S'il y a de meilleures solutions, j'aimerais les voir. Espérons que cela a aidé quelqu'un.
Cela ne ressemble pas à une question. Je ne comprends pas ce que vous demandez. –