我發佈這個,因爲我自己一直在尋找這個問題的明確答案掙扎。 。 。禁用退出(或[X])在tkinter窗口
爲了嘗試爲我的程序創建進度條,我發現使用tkinter很困難。要完成創建進度條而不會遇到可怕的「主循環」,I opted to make a class out of the progress bar using threads。通過大量的試用錯誤,我發現由於使用多線程(tkinter喜歡在主線程中),沒有太多可以定製的東西。這裏有兩個選擇我都試過了,之後是第三最適合我的需求:
選項1:使用一個回調函數
考慮下面的代碼:
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 . . .
凡
self.root.protocol("WM_DELETE_WINDOW", self.__callback)
防止關閉窗口。但是,如果按住Exit或[X]按鈕,則進度條將凍結,直到用戶釋放按鈕。 (__callback函數不斷被調用,阻止其他任務完成)。
選項2:使用root.overriderdirect(真)
考慮下面的代碼:
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 . . .
凡
self.root.overrideredirect(True)
清除所有的tkinters窗口選項。但是,進度條不僅位於一個奇怪的位置,而且也遮蔽了用戶窗口。進度條應該用戶友好。
選項3:使用root.attributes( ' - 禁用',真)
鑑於以下代碼:
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 . . .
凡
self.root.attributes('-disabled', True)
防止與窗口中的任何用戶交互。這最適合我這個程序的需求,因爲它可以防止窗戶關閉,並且仍然具有很好的外觀。 (我唯一的小問題是,用戶不能再將進度條最小化或移動它)。
如果有更好的解決方案,我很樂意看到它們。希望這有助於某人。
這看起來並不像一個問題。我不明白你在問什麼。 –