Ich poste dies, weil ich selbst mit dem Finden einer klaren Antwort auf dieses Problem gekämpft habe. . .Deaktivieren Beenden (oder [X]) in tkinter Fenster
Auf der Suche nach dem Versuch, einen Fortschrittsbalken für mein Programm zu erstellen, finde ich, dass es schwierig ist, mit Tkinter zu tun. Um das Erstellen eines Fortschrittsbalkens zu erreichen, ohne in die gefürchtete "Hauptschleife" zu laufen, I opted to make a class out of the progress bar using threads. Durch viele Versuche habe ich festgestellt, dass es aufgrund der Verwendung von Multithreading nicht viel gibt, das angepasst werden kann (tkinter mag im Hauptthread sein). Hier sind zwei Optionen, die ich versucht habe, um ein Drittel gefolgt, die am besten meine Bedürfnisse paßt:
Option 1: Mit einer Callback-Funktion
mit dem folgenden Code:
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 . . .
Wo
self.root.protocol("WM_DELETE_WINDOW", self.__callback)
Verhindert, dass das Fenster geschlossen wird. Wenn Sie jedoch die Schaltfläche Beenden oder [X] gedrückt halten, wird die Fortschrittsanzeige eingefroren, bis der Benutzer die Schaltfläche loslässt. (Die __callback-Funktion wird ständig aufgerufen, um zu verhindern, dass andere Aufgaben abgeschlossen werden).
Option 2: Verwenden root.overriderdirect (True)
den folgenden Code Gegeben:
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 . . .
Wo
self.root.overrideredirect(True)
alle tkinters Fenster Optionen Löscht. Der Fortschrittsbalken befindet sich jedoch nicht nur an einem ungewöhnlichen Ort, sondern verdeckt auch das Benutzerfenster. Die Fortschrittsanzeige sollte benutzerfreundlich sein.
Option 3: root.attributes Verwendung ('- disabled', True)
der folgende Code Gegeben:
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 . . .
Wo
self.root.attributes('-disabled', True)
Verhindert, dass Benutzer die Interaktion mit dem Fenster . Dies hat meine Bedürfnisse für dieses Programm am besten erfüllt, da es verhindert, dass das Fenster schließt und immer noch ein schönes Aussehen hat. (Mein einziges kleines Problem ist, dass der Benutzer den Fortschrittsbalken nicht länger minimieren oder verschieben kann).
Wenn es bessere Lösungen gibt, würde ich sie gerne sehen. Hoffentlich hat das jemandem geholfen.
Das ist nicht wie eine Frage aussieht. Ich verstehe nicht, was du verlangst. –