Python Tkinter 中的文本输入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15522336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Text Input in Tkinter
提问by IcyFlame
Goal
目标
I am trying to write a basic file which I can import in all other programs that will have a simple function that will take entry from the user and then return it.
我正在尝试编写一个基本文件,我可以将它导入到所有其他程序中,该文件将具有一个简单的函数,该函数将从用户那里获取条目然后返回它。
Code
代码
For that I have the following code:
为此,我有以下代码:
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()
And I also added some script level code so as to test this:
我还添加了一些脚本级别的代码来测试这个:
root = Tk()
getText('enter your name',root)
var = a.getString()
print var
root.mainloop()
And what is really baffling me is that:
真正让我困惑的是:
vardoes not have the value that I entered it has the empty string''a.stringvariable has the value that I entered and I checked this from the shell.
var没有我输入的值 它有空字符串''a.string变量具有我输入的值,我从 shell 中检查了它。
AlsoWhen I tried to assign the string returned from a.getString()to varin the shell, then it worked.
此外,当我尝试在 shell 中分配从a.getString()to返回的字符串时var,它起作用了。
noteI am new to Tkinter programming and dont fully understand how the mainloop()works. So maybe this is were the problem is. But I am not sure.
注意我是 Tkinter 编程的新手,并不完全了解它的mainloop()工作原理。所以也许这就是问题所在。但我不确定。
Specs
眼镜
OS:Linux Mint 14
操作系统:Linux Mint 14
Python IDLE 2.7
Python 空闲 2.7
Pleasehelp me out with this issue.
请帮我解决这个问题。
采纳答案by Kevin
The flow of your code goes like this:
你的代码流程是这样的:
- the main scope calls
getText. getTextcreates atakeInputobjecta.- the
takeInputobject initializes itself, creating Labels & buttons etc. getTextreturnsa.getString(), which returnsself.string, which still has its default value, the empty string.- the main scope prints
var, which is empty.
- 主要作用域调用
getText. getText创建一个takeInput对象a。- 的
takeInput对象初始化自身,创建标签及按钮等 getText返回a.getString(),它返回self.string,它仍然有它的默认值,空字符串。- 主要范围打印
var,这是空的。
So far, all of this has taken place within the span of a few nanoseconds. The user hasn't even seen the window yet.
到目前为止,所有这一切都发生在几纳秒的跨度内。用户甚至还没有看到窗口。
the main scope then calls root.mainloop(), which finally gives the user the opportunity to interact with the window. But it's too late. varhas already been printed.
然后主作用域调用root.mainloop(),这最终让用户有机会与窗口交互。但为时已晚。var已经印刷了。
If you want getTextto not return until the user has submitted his text, then mainloophas to occur inside getText, not after it.
如果你想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
回答by tobias_k
The problem is that your test routine already prints out the value of varbefore the dialog has been shown, let alone text being entered. (You can easily validate this by adding some printstatements to your test code.) This is because the call to mainloop()is at the very end. Instead, you should call mainloopaftercreating the frame, but beforereading and returning the input, e.g. it might go to your getTextmethod:
问题是您的测试例程var在显示对话框之前已经打印出 的值,更不用说输入的文本了。(您可以通过print在测试代码中添加一些语句来轻松验证这一点。)这是因为对 的调用mainloop()位于最后。相反,您应该mainloop在创建框架之后调用,但在读取和返回输入之前调用,例如它可能会转到您的getText方法:
def getText(requestMessage,parent):
a = takeInput(requestMessage,parent)
parent.mainloop()
return a.getString()
This still does not work really well, as you have to close the dialog (click the [x]-button) even after clicking on 'okay', and I am not sure how to fix this.
这仍然不能很好地工作,因为[x]即使在单击“好的”之后您也必须关闭对话框(单击 -按钮),我不知道如何解决这个问题。
However, note that there already isa module for this, tkSimpleDialog, providing methods such as askstring(title, prompt)that show just such an input dialog. So you might either use those, or look at the source code (found in /usr/lib/python2.7/lib-tkor the like) to find out how it's done.
但是,请注意,已经有一个用于此的模块tkSimpleDialog,提供诸如askstring(title, prompt)显示此类输入对话框的方法。因此,您可以使用它们,或者查看源代码(在/usr/lib/python2.7/lib-tk或类似中找到)以了解它是如何完成的。
回答by FabienAndre
As other answers tell, you print varbefore entering the mainloop, that is, before your window is actually running, and your program is waiting for user input.
正如其他答案所说,您var在进入主循环之前打印,即在您的窗口实际运行之前,并且您的程序正在等待用户输入。
You could rely on tkSimpleDialogfamily to get your input:
您可以依靠tkSimpleDialog家人来获取您的意见:
import Tkinter
import tkSimpleDialog
root = Tkinter.Tk()
var = tkSimpleDialog.askstring("Name prompt", "enter your name")
print var
If you want to pursue your way, you could perform your print from the "ok" button callback (gettextin your case). You could also generate a virtual event when "ok" is pressed and bind to this event in your main program (http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/virtual-events.html)
如果您想按照自己的方式进行,您可以从“确定”按钮回调(gettext在您的情况下)执行打印。您还可以在按下“确定”时生成虚拟事件并在主程序中绑定到此事件(http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/virtual-events.html)

