tkinter 窗口中的grab_set

Ern*_*ers 4 python tkinter

我见过许多grab_set() 用于 tkinter 模态窗口的示例,但我无法让它适用于我的应用程序。我正在创建第二个窗口作为我的“设置”窗口,该窗口是从主应用程序的菜单中调用的。

例子:

import tkinter as tk

class Main(tk.Tk):

    def __init__(self,*args, **kwargs):
        tk.Tk.__init__(self,*args, *kwargs)

        button = tk.Button(self,text="second window", command=lambda:Settings())
        button.pack()


class Settings(tk.Tk):

    def __init__(self,*args, **kwargs):
        tk.Tk.__init__(self,*args, *kwargs)
        button = tk.Button(self,text="quit", command=lambda: quit())
        button.pack()
        self.grab_set()

if __name__ == "__main__":
    app = Main()
    app.mainloop()
Run Code Online (Sandbox Code Playgroud)

现在我仍然可以单击“设置”按钮来创建Settings电脑允许的尽可能多的实例。如何限制主应用程序窗口的可点击性,直到第二个窗口先关闭?

Mik*_*SMT 7

这是一个超级简单的示例,说明如何使用打开另一个窗口Toplevel以及如何从顶级窗口编辑主窗口上的内容。

它非常基本,但它应该是一个足够好的示例来说明 tkinter 打开新窗口所需的内容。

更新:添加了grab_set()布莱恩在评论中指出的方法。

grab_set()根据文档的方法将该应用程序的所有事件路由到该小部件。

注意:这将类似于最小、完整和可验证的示例。它是表达要点的尽可能小的代码,同时也是可测试的。

from tkinter import *


class GUI(Frame):
    def __init__(self, master, *args, **kwargs):
        Frame.__init__(self, master, *args, **kwargs)
        
        self.master = master
        self.my_frame = Frame(self.master)
        self.my_frame.pack()

        self.button1 = Button(self.master, text="Open New Window", command = self.open_toplevel_window)
        self.button1.pack()
        
        self.text = Text(self.master, width = 20, height = 3)
        self.text.pack()
        self.text.insert(END, "Before\ntop window\ninteraction")
        
    def open_toplevel_window(self):
        self.top = Toplevel(self.master)
        #this forces all focus on the top level until Toplevel is closed
        self.top.grab_set() 
        
        def replace_text():
            self.text.delete(1.0, END)
            self.text.insert(END, "Text From\nToplevel")
        
        top_button = Button(self.top, text = "Replace text in main window",
                            command = replace_text)
        top_button.pack()


if __name__ == "__main__":
    root = Tk()
    app = GUI(root)
    root.mainloop()
Run Code Online (Sandbox Code Playgroud)

以下是为顶层使用单独的类的示例:

from tkinter import *


class GUI(Frame):
    def __init__(self, master, *args, **kwargs):
        Frame.__init__(self, master, *args, **kwargs)
        
        self.master = master
        self.my_frame = Frame(self.master)
        self.my_frame.pack()

        self.button1 = Button(self.master, text="Open New Window",
                              command = open_toplevel_window)
        self.button1.pack()
        
        self.text = Text(self.master, width = 20, height = 3)
        self.text.pack()
        self.text.insert(END, "Before\ntop window\ninteraction")
        
class open_toplevel_window(Toplevel):
    def __init__(self, *args, **kwargs):
        Toplevel.__init__(self, *args, **kwargs)
        self.grab_set()
        
        def replace_text():
            app.text.delete(1.0, END)
            app.text.insert(END, "Text From\nToplevel")
        
        top_button = Button(self, text = "Replace text in main window",
                            command = replace_text)
        top_button.pack()


if __name__ == "__main__":
    root = Tk()
    app = GUI(root)
    root.mainloop()
Run Code Online (Sandbox Code Playgroud)