首页 文章

在tkinter窗口中的grab_set

提问于
浏览
2

我已经看到很多用于tkinter的模态窗口的grab_set()示例,但是我无法让它为我的应用程序工作 . 我正在创建第二个窗口作为我的“设置”窗口,该窗口从主应用程序的菜单中调用 .

例:

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()

现在我仍然可以单击'Settings'按钮来创建尽可能多的 Settings 实例 . 如何将可点击性限制在主应用程序窗口,直到第二个关闭?

4 回答

  • 1

    这是一个非常简单的示例,说明如何使用 Toplevel 打开另一个窗口,以及如何在Toplevel窗口中编辑主窗口上的内容 .

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

    更新:添加了Bryan在评论中指出的 grab_set() 方法 .

    根据documentationgrab_set() 方法将此应用程序的所有事件路由到此窗口小部件 .

    注意:这将是Minimal, Complete, and Verifiable example的行 . 它是可以测试的最小点代码 .

    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()
    

    以下是为Toplevel使用单独的类时的示例:

    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()
    
  • 0

    我想出了我的问题

    import tkinter as tk
    
    class Main(tk.Tk):
    
        def __init__(self,*args, **kwargs):
            tk.Tk.__init__(self,*args, *kwargs)
    
            self.button = tk.Button(self,text="second window", command=lambda: SecondWindow())
            self.button.pack()
    
    
    class SecondWindow(tk.Toplevel):
    
        def __init__(self,*args, **kwargs):
            tk.Toplevel.__init__(self,*args, *kwargs)
            self.button = tk.Button(self,text="quit", command=lambda: quit())
            self.button.pack()
            self.grab_set()
    
    if __name__ == "__main__":
        app = Main()
        app.mainloop()
    

    根据Sierra Mountain Tech和Bryan Oakley的建议 . 我已将 Settings 类更改为 Toplevel ,它完全符合我的要求 . 我的实际应用程序有两个不同的模块,但产生相同的结果 .

  • 2

    尝试在包含grab_set方法的行之后添加以下行:

    self.wait_window(self)
    
  • 1

    你需要允许焦点与takefocus = True并使用focus_set()给焦点

    def __init__(self, *args, **kwargs):
        Toplevel.__init__(self, *args, **kwargs)
        self.takefocus = True
        self.focus_set()
    

相关问题