在Python中锁定一个Tkinter主窗口,并保持X按钮运行

在Python中锁定一个Tkinter主窗口,并保持X按钮运行,python,tkinter,Python,Tkinter,对不起,如果我没有具体的问题,但它有点长,这是我第一次咨询编程问题。我使用Tkinter模块在Python中创建了一个顶层,我想在主窗口打开时阻止它中的事件。谷歌搜索了一下,我找到了“抓取集”的方法,它把我带到了另一端。也就是说,它会阻止窗口顶部栏中的事件(关闭、最大化和最小化)。是否有类似于grab_set但不发生这种情况的东西 作为替代,我可以阻止所有入口和按钮,但我不知道如何取消链接或重新链接绑定。有办法吗 original = Tk() entrada = Entry(original)

对不起,如果我没有具体的问题,但它有点长,这是我第一次咨询编程问题。我使用Tkinter模块在Python中创建了一个顶层,我想在主窗口打开时阻止它中的事件。谷歌搜索了一下,我找到了“抓取集”的方法,它把我带到了另一端。也就是说,它会阻止窗口顶部栏中的事件(关闭、最大化和最小化)。是否有类似于grab_set但不发生这种情况的东西

作为替代,我可以阻止所有入口和按钮,但我不知道如何取消链接或重新链接绑定。有办法吗

original = Tk()
entrada = Entry(original)
entrada.pack()

def otra_ventana(Self):
    ventana = Toplevel(original)
    ventana.grab_set()

original.bind("<F1>", otra_ventana)
original=Tk()
entrada=条目(原件)
entrada.pack()
def otra_ventana(自我):
文塔纳=顶级(原始)
ventana.grab_set()
原始绑定(“,otra_ventana)
上面的测试代码有我提到的问题

Postscript:只有当Toplevel打开并试图关闭主窗口时,才会出现问题


谢谢。

如果您不喜欢grab_set正在做的事情,那么您可以简单地禁用根窗口中的所有小部件,并在顶级关闭后重新启用它们

使用
winfo_children()
我们可以设置一个函数来切换根窗口中小部件的状态

结合
protocol()

代码:

将tkinter作为tk导入
def切换_root_状态(state='normal'):
对于原始.winfo_children()中的子项:
尝试:
子['state']=状态
除:
通过
def otra_ventana(无):
ventana=tk.顶层(原始)
协议(“WM_DELETE_WINDOW”,lambda:(toggle_root_state(),ventana.destroy())
切换根目录状态(“已禁用”)
original=tk.tk()
原始几何(“225x50”)
entrada=传统条目(原件)
entrada.pack()
原始绑定(“,otra_ventana)
original.mainloop()

准备好了,我做完了。谢谢大家的帮助。对于那些有这个问题的人,我留下了基于我的结论和Mike-SMT代码的解决方案

from tkinter import *

original = Tk()
original.active = True # enter this variable in class Tk
entrada = Entry(original)
entrada.pack()

def toogle(Self=None):
    original.active = not original.active

    for widget in original.winfo_children():
        # only change the state if "state" exists in config and the widget is not Label
        if(widget.config().get("state") and widget.winfo_class() != "Label"):
            widget["state"] = {True:"normal", False:"disabled"}[original.active]

def otra_ventana(Self):
    if(original.active):
        ventana = Toplevel(original)
        ventana.protocol("WM_DELETE_WINDOW", lambda:(toogle(), ventana.destroy()))
        toogle()

original.bind("<F1>", otra_ventana)
从tkinter导入*
原始=Tk()
original.active=True#在Tk类中输入此变量
entrada=条目(原件)
entrada.pack()
def toogle(自身=无):
original.active=非original.active
对于原始.winfo_children()中的小部件:
#只有在配置中存在“状态”且小部件没有标签时才更改状态
如果(widget.config().get(“state”)和widget.winfo_class()!=“Label”):
小部件[“状态”]={True:“正常”,False:“禁用”}[original.active]
def otra_ventana(自我):
如果(原始激活):
文塔纳=顶级(原始)
协议(“WM_DELETE_WINDOW”,lambda:(toogle(),ventana.destroy())
toogle()
原始绑定(“,otra_ventana)

嗨,但丁,欢迎来到SO。请花些时间看一下,它将帮助你写一个好问题。感谢Dorian Turbastovfl的建议,同样感谢链接,但是,正如我前面提到的,grab_set会阻止主窗口顶部栏中的事件。也就是说,我按下主窗口中的关闭按钮,它不会关闭。尝试使用协议,它不起作用。如果你是说等待窗口,它对我也不起作用。这是因为这会暂停代码,但是,例如,我仍然可以在entrys中编写代码,并在主窗口中使用绑定。“再次感谢你。”唐太斯。“保持X按钮运行”:现在我有两个
X
,两个都为我工作?您是否声称无法通过单击
X
关闭任何windwo?我的想法与您相同,但编码不太好。不幸的是,该方法没有停用绑定。我会说“使用解除绑定,然后再次创建”,但我在个人模块中创建绑定,这并没有让它变得如此简单。这就是为什么在问题中,我提到,作为替代方法,使用了一种方法来停用和重新激活绑定。同样,这也是一个可能的解决方案。我正在分析我的模块,我想我可以利用条件和你提出的来实现我想要实现的目标。一旦我准备好了,我会尽快通知你。如果你还想停用绑定,你可以在函数中这样做。@DanteS。我添加了添加或删除绑定的功能。
from tkinter import *

original = Tk()
original.active = True # enter this variable in class Tk
entrada = Entry(original)
entrada.pack()

def toogle(Self=None):
    original.active = not original.active

    for widget in original.winfo_children():
        # only change the state if "state" exists in config and the widget is not Label
        if(widget.config().get("state") and widget.winfo_class() != "Label"):
            widget["state"] = {True:"normal", False:"disabled"}[original.active]

def otra_ventana(Self):
    if(original.active):
        ventana = Toplevel(original)
        ventana.protocol("WM_DELETE_WINDOW", lambda:(toogle(), ventana.destroy()))
        toogle()

original.bind("<F1>", otra_ventana)