2013-03-20 112 views
1

目標文本輸入

我想寫我可以,將有一個簡單的函數,將採取從用戶條目,然後返回它的所有其他程序中導入一個基本的文件。

代碼

對於我有以下代碼:

class takeInput(object): 

    def __init__(self,requestMessage,parent): 

     self.string = '' 
     self.frame = Frame(parent) 
     self.frame.pack()   
     self.acceptInput(requestMessage) 

    def acceptInput(self,requestMessage): 

     r = self.frame 

     k = Label(r,text=requestMessage) 
     k.pack(side='left') 
     self.e = Entry(r,text='Name') 
     self.e.pack(side='left') 
     self.e.focus_set() 
     b = Button(r,text='okay',command=self.gettext) 
     b.pack(side='right') 

    def gettext(self): 
     self.string = self.e.get() 
     self.frame.destroy() 
     print self.string 

    def getString(self): 
     return self.string 

def getText(requestMessage,parent): 
    global a 
    a = takeInput(requestMessage,parent) 
    return a.getString() 

而且我還添加了一些腳本級的代碼,以便測試:

root = Tk() 

getText('enter your name',root) 

var = a.getString() 

print var 

root.mainloop() 

什麼是真是莫名其妙:

  1. var沒有,我進入它具有空字符串''
  2. a.string變了,我進入我查這起殼價值的價值。

當我試圖指定字符串從a.getString()在shell回到var,然後它的工作。

note我是Tkinter編程的新手,完全不瞭解mainloop()的工作原理。所以也許這是問題所在。但我不確定。

規格

操作系統:Linux Mint的14

Python的IDLE 2.7

幫我出這個問題。

+1

Mainloop只不過是一個類似'while the_main_window_exists():get_the_next_event()'的無限循環。 process_the_event()'。沒有什麼特別神祕的。 – 2013-03-20 12:28:46

回答

7

你的代碼的流程是這樣的:

  • 主要適用範圍調用getText
  • getText創建takeInput對象a
  • takeInput對象初始化自身,創建標籤&按鈕等
  • getText回報a.getString(),它返回self.string,仍然有它的默認值,空字符串。
  • 主要範圍打印var,這是空的。

到目前爲止,所有這些都發生在幾納秒的範圍內。用戶甚至還沒有看到窗口。

主範圍然後調用root.mainloop(),這最終給用戶提供了與窗口交互的機會。但爲時已晚。var已經被打印。

如果您希望getText在用戶提交文本之前不會返回,則mainloop必須在getText之內發生,而不是在其之後。

from Tkinter import * 

class takeInput(object): 

    def __init__(self,requestMessage): 
     self.root = Tk() 
     self.string = '' 
     self.frame = Frame(self.root) 
     self.frame.pack()   
     self.acceptInput(requestMessage) 

    def acceptInput(self,requestMessage): 
     r = self.frame 

     k = Label(r,text=requestMessage) 
     k.pack(side='left') 
     self.e = Entry(r,text='Name') 
     self.e.pack(side='left') 
     self.e.focus_set() 
     b = Button(r,text='okay',command=self.gettext) 
     b.pack(side='right') 

    def gettext(self): 
     self.string = self.e.get() 
     self.root.destroy() 

    def getString(self): 
     return self.string 

    def waitForInput(self): 
     self.root.mainloop() 

def getText(requestMessage): 
    msgBox = takeInput(requestMessage) 
    #loop until the user makes a decision and the window is destroyed 
    msgBox.waitForInput() 
    return msgBox.getString() 

var = getText('enter your name') 
print "Var:", var 
+0

先生,它會被罰款,如果我只是打印出值後,我做的'主循環()'?那是對的嗎?我檢查了它,它確實有效。 – IcyFlame 2013-03-20 15:53:36

1

的問題是,你的測試程序已經打印出的var值之前已經所示的對話框,讓正在進入單獨的文本。 (你可以很容易地通過添加一些print語句測試代碼驗證這一點。)這是因爲調用mainloop()是在最後。相反,你應該叫mainloop創建幀之後,但之前閱讀並返回輸入,例如它可能會去你的getText方法:

def getText(requestMessage,parent): 
    a = takeInput(requestMessage,parent) 
    parent.mainloop() 
    return a.getString() 

這仍然沒有工作非常好,因爲你必須關閉對話框(點擊[x] - 按鈕),即使點擊「好」之後,我不知道如何解決這個問題。

但是請注意,有已經爲此,tkSimpleDialog模塊,提供了方法,如askstring(title, prompt),顯示了這樣一個輸入對話框。所以,你可能要麼使用那些,或者看看源代碼(在/usr/lib/python2.7/lib-tk或類似的發現)來找出它是如何做。

+0

「你必須關閉框架,即使點擊好」後。這是因爲「okay」按鈕的回調只會破壞框架。根窗口仍然未被銷燬,所以'mainloop'將繼續循環。如果你在回調中摧毀了根目錄,而不是摧毀框架,那麼'mainloop'將會結束。 – Kevin 2013-03-20 12:29:54

+0

@Kevin是的,是這麼認爲的,但我不知道是什麼創造這個輸入從另一個Tk的框架內對話框時,這會怎麼做。 – 2013-03-20 12:32:49

+0

不,先生。我不打算關閉窗口,因爲我必須在我正在構建的應用程序中打印一些其他內容。 – IcyFlame 2013-03-20 15:52:54

10

至於其他的答案告訴你在進入主循環之前打印var,就是以前你的窗口實際運行,你的程序是等待用戶輸入。

你可以依靠tkSimpleDialog家庭,讓您的輸入:

import Tkinter 
import tkSimpleDialog 

root = Tkinter.Tk() 
var = tkSimpleDialog.askstring("Name prompt", "enter your name") 
print var 

如果你想追求你的方式,你可以從「確定」按鈕回調執行打印(在你的情況gettext)。您也可以在按下「ok」並在您的主程序中綁定到此事件時生成一個虛擬事件(http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/virtual-events.html

+0

是的。我發現這是做事最簡單的方法! – IcyFlame 2013-03-21 08:06:04