2017-07-18 228 views
1

我見過很多用於tkinter模式窗口的grab_set()的例子,但我無法讓它爲我的應用程序工作。 我正在創建第二個窗口作爲我的「設置」窗口,它是從主應用程序的菜單中調用的。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的多個實例作爲PC將允許。我如何限制對主應用程序窗口的可點擊性,直到第二個窗口被關閉爲止?

+0

這裏沒有可測試的代碼。請提供[最小,完整和可驗證示例](https://stackoverflow.com/help/mcve)。 –

+0

你說你在第二個進程中有第二個窗口,但是我的代碼中沒有看到任何內容,表明你正在運行一個單獨的進程。 –

+0

至少從我的理解。當在tkinter中打開單獨的應用程序窗口時,它們使用單​​獨的進程(因爲它們每個都有自己的任務欄圖標),但我可能錯了。我在帖子中讀到,如果他們的應用程序窗口不共享相同的進程,那麼grab_set將不起作用。我也可以在我的頭上,雖然 –

回答

2

下面是一個非常簡單的例子,介紹如何使用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() 

這裏使用一個單獨的類頂層時是一個例子:

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

由於原來的問題是關於抓鬥,如果你在新的頂層中包含抓取,這個例子會更好。 –

+0

@BryanOakley:添加了帶有註釋的'grab_set()'方法。感謝您的關注。 –

+1

謝謝你們的例子。我發佈了我的修復程序,但需要給予SierraMountainTech和@BryanOakley信用,最終爲我解決問題提供了答案。 –

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

按照內華達山科技和Bryan Oakley的建議。我已將Settings課程更改爲Toplevel,並且它完全符合我的要求。 我的acutal應用程序有兩個不同的模塊,但產生相同的結果。

+0

我很高興你明白了。我只是更新我的答案,包括第二級頂級:) –

+0

這是一個很好的例子,說明爲什麼創建一個[mcve]很重要。將問題縮小到可能的最小范例,可以更容易地查明問題所在。 –

+0

我絕對需要練習使用Minimal Complete和Verifiable示例。我感謝你指導我正確的方向。 –