python-在tkinter窗口中禁用退出(或[X])
作者:互联网
我之所以发布此消息,是因为我自己一直在努力寻找有关此问题的明确答案. . .
为了尝试为我的程序创建进度条,我发现使用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)
防止关闭窗口.但是,如果要按住“退出”或[X]按钮,则进度条将冻结,直到用户释放该按钮. (__callback函数不断被调用,以防止其他任务完成).
选项2:使用root.overriderdirect(True)
给出以下代码:
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(‘-disabled’,True)
给出以下代码:
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)
防止用户与窗口进行任何交互.这最适合我对该程序的需求,因为它可以防止窗口关闭并且外观仍然很好. (我唯一的次要问题是用户无法再最小化进度条或将其移走).
如果有更好的解决方案,我很乐意看到它们.希望这对某人有所帮助.
解决方法:
您可以创建一个仅使用pass而不执行任何操作的函数.
看一下下面的内容:
import tkinter as tk
root=tk.Tk()
def close_program():
root.destroy()
def disable_event():
pass
btn = tk.Button(root, text = "Click me to close", command = close_program)
btn.pack()
root.protocol("WM_DELETE_WINDOW", disable_event)
root.mainloop()
您还可以将工具栏与root.overrideredirect(True)一起删除,这将阻止用户使用任何工具栏.离开root.protocol(“ WM_DELETE_WINDOW”,disable_event)也将阻止使用ALT F4.
import tkinter as tk
root=tk.Tk()
root.geometry("400x400")
root.overrideredirect(True)
def close_program():
root.destroy()
def disable_event():
pass
btn = tk.Button(root, text = "Click me to close", command = close_program)
btn.pack()
root.protocol("WM_DELETE_WINDOW", disable_event)
root.mainloop()
标签:python-3-x,tkinter,exit,progress-bar,python 来源: https://codeday.me/bug/20191111/2017425.html