2015-04-07 33 views
2

我有一個Tkinter的類:創建的Tkinter類,並等待一個返回值

class DBCreatorWin(): 
    def closeWindow(self): 
     tkMessageBox.showinfo("Ilmiont SQLite Database Manager", "This window cannot be closed.\nEnter a database name and press Continue.") 

    def returnName(self): 
     dbName = self.entry.get() 
     self.window.destroy() 
     return dbName 

    def __init__(self): 
     self.window = Toplevel() 
     self.window.transient(tkRoot) 
     self.window.grab_set() 
     self.window.resizable(width=False, height=False) 
     self.window.title("Ilmiont SQLite Database Manager") 
     self.window.protocol("WM_DELETE_WINDOW", self.closeWindow) 

     self.label = Label(self.window, text="Enter the name of the database to be created: ") 
     self.entry = Entry(self.window, width=30) 
     self.button = Button(self.window, text="Continue", command=self.returnName) 
     self.label.grid(row=0, column=0) 
     self.entry.grid(row=0, column=1) 
     self.button.grid(row=1, column=0, columnspan=2) 

我想我的主要代碼中創建這個類的一個實例,並等待返回值。用戶在輸入字段中輸入名稱並按下繼續按鈕。此時,該值應該返回到類最初實例化的地方。我如何去做這件事?我似乎無法以正常的方式使其工作,並且對tkinter是新的。

由於提前, Ilmiont

+0

調用'mainloop'直到窗口關閉後,代碼的正常流程將不會繼續。如果您希望GUI保持打開狀態,則必須從GUI內調用代碼邏輯。沒有[minimal example](http://stackoverflow.com/help/mcve),很難說你現在做錯了什麼。 – jonrsharpe

+0

聽起來像你可能想使用類似['easygui'](http://easygui.sourceforge.net/)模塊的東西,而不是事件驅動。 – martineau

回答

5

有幾種方法可以做到這一點。基本思想是在返回之前使用tkinter方法等待特定的事件。 Tkinter提供了兩種方法:wait_windowwait_variable。最常見的方法是打開一個窗口,然後等待它被銷燬。一些很好的例子可以在effbot網站上找到,標題爲Dialog Windows

下面是一個簡單的例子。這不是生產準備,但說明了總體思路。至少你會想在對話框中添加一個抓取點,以便在對話框打開的時候你不能與主窗口進行交互,因爲你說你希望對話框是模態的。

import Tkinter as tk 
class MyDialog(object): 
    def __init__(self, parent): 
     self.toplevel = tk.Toplevel(parent) 
     self.var = tk.StringVar() 
     label = tk.Label(self.toplevel, text="Pick something:") 
     om = tk.OptionMenu(self.toplevel, self.var, "one", "two","three") 
     button = tk.Button(self.toplevel, text="OK", command=self.toplevel.destroy) 
     label.pack(side="top", fill="x") 
     om.pack(side="top", fill="x") 
     button.pack() 

    def show(self): 
     self.toplevel.deiconify() 
     self.toplevel.wait_window() 
     value = self.var.get() 
     return value 


class Example(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 

     self.button = tk.Button(self, text="Click me!", command=self.on_click) 
     self.label = tk.Label(self, width=80) 
     self.label.pack(side="top", fill="x") 
     self.button.pack(pady=20) 

    def on_click(self): 
     result = MyDialog(self).show() 
     self.label.configure(text="your result: %s" % result) 

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

感謝您的解決方案。它運作良好。經過一些額外的狩獵之後,我遇到了tkSimpleDialog.askstring,它實際上很好地解決了我的問題。 – Ilmiont

-1

你不能。

tkinter的整個工作方式是回調。你使用的命令是回調,你必須使用類中的值。這裏是一個例子:

def do_stuf(self): 
    tkMessageBox.showinfo("Foo", returnName()) 

        .................... 

self.button = Button(self.window, text="Continue", command=self.do_stuff) 
+1

「你不能」是不正確的。 –