在 tkinter 中创建消息框时禁用 window 控件
Disable window controls when a messagebox is created in tkinter
在 tkinter 中创建消息框弹出窗口时,有什么方法可以禁用所有 windows 吗?
代码如下:
from tkinter import *
from tkinter import messagebox
def show():
messagebox.showinfo("Test Popup", "Hello world")
root = Tk()
root.title("Main Window")
root.geometry("500x500")
toplevel = Toplevel(root)
toplevel.title("Toplevel Window")
toplevel.geometry("300x300")
show_button = Button(root , text = "Show popup" , command = show)
show_button.place(x = 200 , y = 200)
mainloop()
这里,当消息框弹出时,我不希望用户能够与任何其他 Tk
或 Toplevel
windows 交互,直到该弹出窗口被销毁。
(我尝试使用 messagebox
的 parent
属性,但它只禁用了一个 window。)
有什么方法可以在 tkinter 中实现吗?
如果有人能帮助我就太好了。
我认为不可能阻止与 windows 的所有交互,例如移动它们(除非您使用 .overrideredirect(True)
这将使 window 装饰消失并且寡妇将不再由 window 经理处理。
但是,可以
防止顶层出现在弹出窗口的顶部
显示弹出窗口时禁用根 window 和顶层的“关闭”按钮
对于两者,我在 show()
中都使用了以下总体思路:
def show():
# modify state of root and toplevel to make them less interactive
# ...
messagebox.showinfo("Test Popup", "Hello world", parent=root)
# put root and toplevel back in their normal state
# ...
对于 1. 我在显示弹出窗口之前使用 root.attributes('-topmost', True)
,它从 root
继承了这个 属性,因此将停留在 toplevel
.[=25 之上=]
对于 2。我使用 window.protocol("WM_DELETE_WINDOW", lambda: quit(window))
,当用户单击 window 的关闭按钮时调用 quit(window)
。在 quit()
中,我在销毁 window:
之前检查弹出窗口是否打开
def quit(window):
if not popup:
window.destroy()
popup
是一个全局变量,其值在 show()
中发生变化。
完整代码:
import tkinter as tk
from tkinter import messagebox
def quit(window):
if not popup: # destroy the window only if popup is not displayed
window.destroy()
def show():
global popup
popup = True
root.attributes('-topmost', True)
messagebox.showinfo("Test Popup", "Hello world", parent=root)
root.attributes('-topmost', False)
popup = False
root = tk.Tk()
popup = False
root.protocol("WM_DELETE_WINDOW", lambda: quit(root))
root.title("Main Window")
root.geometry("500x500")
toplevel = tk.Toplevel(root)
toplevel.protocol("WM_DELETE_WINDOW", lambda: quit(toplevel))
toplevel.title("Toplevel Window")
show_button = tk.Button(root, text="Show popup", command=show)
show_button.pack()
root.mainloop()
您或许可以在 show()
中添加更多内容,例如.resizable(False, False)
如果您不希望用户在显示弹出窗口时能够调整 windows 的大小。
经过几天的试验,终于找到了解决办法。
这里的基本思路是获取window的所有子widget,检查子widget是Tk
还是Toplevel
的实例,然后应用-disabled
属性。
实现如下:
from tkinter import *
from tkinter import messagebox
def disable_windows(window):
for child in window.winfo_children(): # Get all the child widgets of the window
if isinstance(child, Tk) or isinstance(child, Toplevel): # Check if the child is a Tk or Toplevel window so that we can disable them
child.attributes('-disabled', True)
disable_windows(child)
def enable_windows(window):
for child in window.winfo_children(): # Get all the child widgets of the window
if isinstance(child , Tk) or isinstance(child , Toplevel): # Check if the child is a Tk or Toplevel window so that we can enable them
child.attributes('-disabled' , False)
enable_windows(child)
def increase_popup_count():
global popup_count
popup_count += 1
if popup_count > 0: # Check if a popup is currently active so that we can disable the windows
disable_windows(root)
else: # Enable the windows if there is no active popup
enable_windows(root)
def decrease_popup_count():
global popup_count
popup_count -= 1
if popup_count > 0: # Check if a popup is currently active so that we can disable the windows
disable_windows(root)
else: # Enable the windows if there is no active popup
enable_windows(root)
def showinfo(title, message): # A custom showinfo funtion
increase_popup_count() # Increase the 'popup_count' when the messagebox shows up
messagebox.showinfo(title , message)
decrease_popup_count() # Decrease the 'popup_count' after the messagebox is destroyed
def show():
showinfo("Test Popup", "Hello world")
root = Tk()
root.title("Main Window")
root.geometry("500x500")
popup_count = 0
toplevel = Toplevel(root)
toplevel.title("Toplevel Window")
toplevel.geometry("400x400")
toplevel_2 = Toplevel(toplevel)
toplevel_2.title("Toplevel Window of Another Toplevel")
toplevel_2.geometry("300x300")
show_button = Button(root , text = "Show popup" , command = show)
show_button.place(x = 200 , y = 200)
mainloop()
在 tkinter 中创建消息框弹出窗口时,有什么方法可以禁用所有 windows 吗?
代码如下:
from tkinter import *
from tkinter import messagebox
def show():
messagebox.showinfo("Test Popup", "Hello world")
root = Tk()
root.title("Main Window")
root.geometry("500x500")
toplevel = Toplevel(root)
toplevel.title("Toplevel Window")
toplevel.geometry("300x300")
show_button = Button(root , text = "Show popup" , command = show)
show_button.place(x = 200 , y = 200)
mainloop()
这里,当消息框弹出时,我不希望用户能够与任何其他 Tk
或 Toplevel
windows 交互,直到该弹出窗口被销毁。
(我尝试使用 messagebox
的 parent
属性,但它只禁用了一个 window。)
有什么方法可以在 tkinter 中实现吗?
如果有人能帮助我就太好了。
我认为不可能阻止与 windows 的所有交互,例如移动它们(除非您使用 .overrideredirect(True)
这将使 window 装饰消失并且寡妇将不再由 window 经理处理。
但是,可以
防止顶层出现在弹出窗口的顶部
显示弹出窗口时禁用根 window 和顶层的“关闭”按钮
对于两者,我在 show()
中都使用了以下总体思路:
def show():
# modify state of root and toplevel to make them less interactive
# ...
messagebox.showinfo("Test Popup", "Hello world", parent=root)
# put root and toplevel back in their normal state
# ...
对于 1. 我在显示弹出窗口之前使用 root.attributes('-topmost', True)
,它从 root
继承了这个 属性,因此将停留在 toplevel
.[=25 之上=]
对于 2。我使用 window.protocol("WM_DELETE_WINDOW", lambda: quit(window))
,当用户单击 window 的关闭按钮时调用 quit(window)
。在 quit()
中,我在销毁 window:
def quit(window):
if not popup:
window.destroy()
popup
是一个全局变量,其值在 show()
中发生变化。
完整代码:
import tkinter as tk
from tkinter import messagebox
def quit(window):
if not popup: # destroy the window only if popup is not displayed
window.destroy()
def show():
global popup
popup = True
root.attributes('-topmost', True)
messagebox.showinfo("Test Popup", "Hello world", parent=root)
root.attributes('-topmost', False)
popup = False
root = tk.Tk()
popup = False
root.protocol("WM_DELETE_WINDOW", lambda: quit(root))
root.title("Main Window")
root.geometry("500x500")
toplevel = tk.Toplevel(root)
toplevel.protocol("WM_DELETE_WINDOW", lambda: quit(toplevel))
toplevel.title("Toplevel Window")
show_button = tk.Button(root, text="Show popup", command=show)
show_button.pack()
root.mainloop()
您或许可以在 show()
中添加更多内容,例如.resizable(False, False)
如果您不希望用户在显示弹出窗口时能够调整 windows 的大小。
经过几天的试验,终于找到了解决办法。
这里的基本思路是获取window的所有子widget,检查子widget是Tk
还是Toplevel
的实例,然后应用-disabled
属性。
实现如下:
from tkinter import *
from tkinter import messagebox
def disable_windows(window):
for child in window.winfo_children(): # Get all the child widgets of the window
if isinstance(child, Tk) or isinstance(child, Toplevel): # Check if the child is a Tk or Toplevel window so that we can disable them
child.attributes('-disabled', True)
disable_windows(child)
def enable_windows(window):
for child in window.winfo_children(): # Get all the child widgets of the window
if isinstance(child , Tk) or isinstance(child , Toplevel): # Check if the child is a Tk or Toplevel window so that we can enable them
child.attributes('-disabled' , False)
enable_windows(child)
def increase_popup_count():
global popup_count
popup_count += 1
if popup_count > 0: # Check if a popup is currently active so that we can disable the windows
disable_windows(root)
else: # Enable the windows if there is no active popup
enable_windows(root)
def decrease_popup_count():
global popup_count
popup_count -= 1
if popup_count > 0: # Check if a popup is currently active so that we can disable the windows
disable_windows(root)
else: # Enable the windows if there is no active popup
enable_windows(root)
def showinfo(title, message): # A custom showinfo funtion
increase_popup_count() # Increase the 'popup_count' when the messagebox shows up
messagebox.showinfo(title , message)
decrease_popup_count() # Decrease the 'popup_count' after the messagebox is destroyed
def show():
showinfo("Test Popup", "Hello world")
root = Tk()
root.title("Main Window")
root.geometry("500x500")
popup_count = 0
toplevel = Toplevel(root)
toplevel.title("Toplevel Window")
toplevel.geometry("400x400")
toplevel_2 = Toplevel(toplevel)
toplevel_2.title("Toplevel Window of Another Toplevel")
toplevel_2.geometry("300x300")
show_button = Button(root , text = "Show popup" , command = show)
show_button.place(x = 200 , y = 200)
mainloop()