2013-04-17 109 views
1

如何從一個0屬性函數的tkinter toplevel中獲取值?如何從0屬性函數中的tkinter toplevel中獲取值?

def Update(): 
    Up = Toplevel() 
    Up.title("Update") 
    taskLabel = Label(Up, text ="Update", font=('Times', 20)).grid(row=0) 

    var = IntVar() 
    radio = Radiobutton(Up, text="Fully", variable=var, value=1, command = taskUpdate).grid(row=2, sticky=W) 

    radio = Radiobutton(Up, text="Partly", variable=var, value=2, command = taskUpdate).grid(row=3, sticky=W) 

    radio = Radiobutton(Up, text="Un", variable=var, value=3, command = taskUpdate).grid(row=4, sticky=W) 

    note = EntryaUp, width=30, font=('Arial', 12,)).grid(row=6) 
    Button = Button(Up, text ="Task Complete and Send Invoice", command = taskUpdate).grid(row =7) 

    return (var, note) 

def updateB(): 
    var, noteBox = Update() 
    a = (var.get()) 
    b = (note.get()) 

這是Tkinter的一個頂層窗口和我想要得到的值1,2,3,當我點擊單選按鈕,當我在輸入文本獲取字符串值輸入並點擊命令按鈕,但我不知道該怎麼做。順便說一下,我不認爲我可以返回任何值,每當它返回時它只返回初始值0和「」。我知道它是如何工作的,如果單選按鈕不在頂層(或在函數中),它可以得到值。但我無法弄清楚,如果結構是這樣的,我該怎麼做。

回答

5

您的問題的簡短答案是,您可以使用wait_window()等待窗口被解僱,然後您可以從您的功能返回任何你想要的。然後你會連接你的「任務完成」按鈕來簡單地銷燬窗口。

你必須非常小心,在這裏 - wait_window創建一個新嵌套事件循環。大多數情況下,這與窗口抓取一起完成,以防止處理其他窗口中的事件。當你這樣做時,你正在創建一個模態對話框。

下面是一個工作示例;我不得不調整你的代碼一點點,我把消除一些不必要的變量的自由(如對單選按鈕的引用,因爲你永遠不會做與引用任何東西)

import Tkinter as tk # python 2.7 

class Example(tk.Frame): 
    def __init__(self, *args, **kwargs): 
     tk.Frame.__init__(self, *args, **kwargs) 
     button = tk.Button(self, text="Open window", command=self.on_button) 
     button.pack() 

    def on_button(self): 
     var, note = Update() 
     a = var.get() 
     b = note.get() 
     print "a: '%s' b: '%s'" % (a,b) 

def Update(): 
    Up = tk.Toplevel() 
    Up.title("Update") 
    tk.Label(Up, text ="Update", font=('Times', 20)).grid(row=0) 

    var = tk.IntVar() 
    tk.Radiobutton(Up, text="Fully", variable=var, value=1).grid(row=2, sticky="w") 
    tk.Radiobutton(Up, text="Partly", variable=var, value=2).grid(row=3, sticky="w") 
    tk.Radiobutton(Up, text="Un", variable=var, value=3).grid(row=4, sticky="w") 

    evar = tk.StringVar() 
    note = tk.Entry(Up, width=30, font=('Arial', 12,), textvariable=evar) 
    note.grid(row=6) 

    Button = tk.Button(Up, text ="Task Complete and Send Invoice", command = Up.destroy).grid(row =7) 

    Up.wait_window() 
    print "done waiting..." 
    return (var, evar) 

if __name__ == "__main__": 
    root = tk.Tk() 
    Example(root).pack(side="top", fill="both", expand=True) 
    root.mainloop() 

要明白,你爲什麼一定要小心使用此功能時,請嘗試以下場景:「打開窗口」按鈕

  1. 點擊,填寫表格,然後點擊「任務完成」按鈕。請注意,它可能以您期望的方式工作(打印到標準輸出,因此請確保您從控制檯窗口運行)

  2. 單擊「打開窗口」按鈕,然後再次單擊它。你現在有兩個窗口。填寫第二個窗口,點擊「任務完成」,注意它可以像你期望的那樣工作。現在填寫第一個窗口並點擊「任務完成」,它仍然可以正常工作。在這兩種情況下,當你點擊按鈕時,它將正確的值輸出到屏幕上。

  3. 點擊「打開窗口」按鈕,然後再次點擊它。你現在有兩個窗口。這一次,填寫第一個窗口,然後單擊「任務完成」。請注意,它不是而是將結果打印到屏幕上。這是因爲在第三個窗口的嵌套事件循環完成之前,第一個窗口的嵌套事件循環無法完成。填寫第二個窗口的窗體並點擊「Task Complete」,你會看到兩個嵌套的事件循環展開,但不是按照你點擊「Task Complete」的順序,而是按照窗口的順序創建。

這就是爲什麼你需要使用wait_window時要小心 - 你應該阻止事件循環的這個遞歸嵌套或您的GUI可能無法正常使用你期望的方式。

+0

嗨@BryanOakley這是完全可怕的答案,你在那裏。非常感謝!一個小問題,在'def __init __(self,* args,** kwargs)'方面有什麼是'* args,** kwargs':'並且當我把'tk.Frame .__ init __(self,* args,** kwargs )button = tk.Button(self,text =「Open window」,command = self.on_button.destroy)'爲什麼'function'對象沒有屬性'destroy' – PyJar

+0

@PyJar:'self.on_button'是一個函數,所以它沒有'destroy'方法。 'destroy'是一個小部件的標準方法,而不是函數。 '* args'和'** kwargs''是一個可變數量的參數和關鍵字參數的標準python成語。 –

相關問題