tkinter窗口中的grab_set

时间:2017-07-18 15:35:27

标签: python tkinter

我已经看到很多用于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实例,因为它可以允许。如何将可点击性限制在主应用程序窗口中,直到第一个关闭它?

4 个答案:

答案 0 :(得分:2)

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

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

更新:添加了布莱恩在评论中指出的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()

答案 1 :(得分:1)

我想出了我的问题

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 :(得分:1)

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

self.wait_window(self)

答案 3 :(得分:0)

您需要使用takefocus = True允许焦点,并使用focus_set()赋予焦点

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