Python Tkinter中的文本输入

Python Tkinter中的文本输入,python,tkinter,Python,Tkinter,目标 我试图写一个基本的文件,我可以导入到所有其他程序中,这些程序将有一个简单的函数,从用户那里获取条目,然后返回它 代码 为此,我有以下代码: class takeInput(object): def __init__(self,requestMessage,parent): self.string = '' self.frame = Frame(parent) self.frame.pack() se

目标

我试图写一个基本的文件,我可以导入到所有其他程序中,这些程序将有一个简单的函数,从用户那里获取条目,然后返回它

代码

为此,我有以下代码:

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()
真正让我困惑的是:

var没有我输入的值,它有空字符串 a、 字符串变量具有我输入的值,我从shell中对此进行了检查。 另外,当我尝试将从.getString返回的字符串分配给shell中的var时,它也起了作用

注:我是Tkinter编程新手,不完全了解主循环是如何工作的。所以也许这就是问题所在。但我不确定

规格

操作系统:Linux Mint 14

Python IDLE 2.7


请帮我解决这个问题。

您的代码流程如下:

主作用域调用getText。 getText创建一个takeInput对象a。 takeInput对象自身初始化,创建标签和按钮等。 getText返回一个.getString,它返回self.string,它仍然有默认值,即空字符串。 主作用域打印变量,该变量为空。 到目前为止,所有这些都发生在几纳秒的范围内。用户甚至还没有看到窗口

然后,主作用域调用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

您的代码流程如下所示:

主作用域调用getText。 getText创建一个takeInput对象a。 takeInput对象自身初始化,创建标签和按钮等。 getText返回一个.getString,它返回self.string,它仍然有默认值,即空字符串。 主作用域打印变量,该变量为空。 到目前为止,所有这些都发生在几纳秒的范围内。用户甚至还没有看到窗口

然后,主作用域调用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

问题是,在显示对话框之前,测试例程已经打印出var的值,更不用说输入文本了。通过向测试代码中添加一些print语句,您可以轻松地验证这一点。这是因为对mainloop的调用在最后。相反,您应该在创建帧之后,但在读取和返回输入之前调用mainloop,例如,它可能会转到getText方法:

这仍然不能很好地工作,因为即使在单击“确定”之后,您也必须关闭对话框并单击[x]-按钮,我不确定如何修复此问题


但是,请注意,已经有了一个模块tkSimpleDialog,它提供了一些方法,如askstringtitle、prompt,这些方法只显示这样一个输入对话框。因此,您可以使用它们,也可以查看/usr/lib/python2.7/lib-tk或类似文件中的源代码,以了解它是如何完成的。

问题是,您的测试例程在显示对话框之前已经打印出var的值,更不用说输入文本了。通过向测试代码中添加一些print语句,您可以轻松地验证这一点。这是因为对mainloop的调用在最后。相反,您应该在创建帧之后,但在读取和返回输入之前调用mainloop,例如,它可能会转到getText方法:

这仍然不能很好地工作,因为即使在单击“确定”之后,您也必须关闭对话框并单击[x]-按钮,我不确定如何修复此问题


但是,请注意,已经有了一个模块tkSimpleDialog,它提供了一些方法,如askstringtitle、prompt,这些方法只显示这样一个输入对话框。因此,您可以使用它们,或者查看/usr/lib/python2.7/lib-tk或类似文件中的源代码,以了解它是如何完成的。

正如其他答案所述,您在进入主循环之前打印var,也就是说,在您的窗口实际运行之前,您的程序正在等待用户输入

您可以依靠tkSimpleDialog系列获得您的输入:

import Tkinter
import tkSimpleDialog

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

如果您想继续您的方式,您可以在您的案例中通过ok按钮回调gettext执行打印。您还可以在按下ok时生成一个虚拟事件,并绑定到主程序中的该事件

正如其他答案所示,您在进入主循环之前(即,在窗口实际运行之前)打印var,并且您的程序正在等待用户输入

您可以依靠tkSimpleDialog系列获得您的输入:

import Tkinter
import tkSimpleDialog

root = Tkinter.Tk()
var = tkSimpleDialog.askstring("Name prompt", "enter your name")
print var
如果您想继续您的方式,您可以在您的案例中通过ok按钮回调gettext执行打印。你
也可以在按下ok时生成一个虚拟事件,并绑定到主程序中的该事件

import tkinter
from tkinter import simpledialog

root = tkinter.Tk()
# withdraw() will make the parent window disappear.
root.withdraw()
# shows a dialogue with a string input field
youtube_url = simpledialog.askstring('YouTube URL', 'Enter the youtube URL of the video', parent=root)

if str(youtube_url).startswith('http'):
    pass
else:
    pass

下面是一个简短的片段:

import tkinter
from tkinter import simpledialog

root = tkinter.Tk()
# withdraw() will make the parent window disappear.
root.withdraw()
# shows a dialogue with a string input field
youtube_url = simpledialog.askstring('YouTube URL', 'Enter the youtube URL of the video', parent=root)

if str(youtube_url).startswith('http'):
    pass
else:
    pass

Mainloop只不过是一个无限循环,它大致类似于主窗口存在时的情况:获取下一个事件;处理事件。它并没有什么特别神秘的地方。Mainloop不过是一个无限循环,大致上看起来像是当主窗口存在时:获取下一个事件;处理事件。没有什么特别神秘的。你必须关闭框架,即使在点击OK之后。这是因为“确定”按钮的回调只会破坏帧。根窗口仍然未被删除,因此mainloop将继续循环。如果您在回调中销毁根,而不仅仅是销毁帧,那么mainloop将结束。@Kevin是的,我也这么认为,但我不确定从另一个Tk帧中创建此输入对话框时会做什么。不,先生。我不打算关闭窗口,因为我必须在正在构建的应用程序中打印一些其他内容。即使在单击“确定”后,您也必须关闭框架。这是因为“确定”按钮的回调只会破坏帧。根窗口仍然未被删除,因此mainloop将继续循环。如果您在回调中销毁根,而不仅仅是销毁帧,那么mainloop将结束。@Kevin是的,我也这么认为,但我不确定从另一个Tk帧中创建此输入对话框时会做什么。不,先生。我不打算关闭窗口,因为我必须在我正在构建的应用程序中打印一些其他内容。先生:如果我在执行mainloop之后只打印值,可以吗?对吗?我检查过了,它确实起作用了。先生:在我做mainloop之后,如果我只打印值就可以了吗?对吗?我检查过了,确实有效。我发现这是最简单的做事方式!对我发现这是最简单的做事方式!最好是解释,你在做什么,这样人们会发现它有用,即使是以评论的形式。最好是解释,你在做什么,这样人们会发现它有用,即使是以评论的形式