Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 文本输入事件?_Python_User Interface_Events_Tkinter_Tkinter Entry - Fatal编程技术网

Python 文本输入事件?

Python 文本输入事件?,python,user-interface,events,tkinter,tkinter-entry,Python,User Interface,Events,Tkinter,Tkinter Entry,作为我程序的一部分,我向用户询问他们的姓名和班级(高中班级)。一旦用户在输入姓名后按“回车”,按钮将被禁用,并显示“导师”字段。然而,用户本质上能够提交他们的名字,即使他们没有键入任何东西。我只希望在用户开始键入后“回车”按钮处于活动状态 我在下面所做的似乎不起作用:( 此外,我的输入验证不起作用-知道为什么吗 class Enter_Name_Window(tk.Toplevel): '''A simple instruction window''' def __init__(

作为我程序的一部分,我向用户询问他们的姓名和班级(高中班级)。一旦用户在输入姓名后按“回车”,按钮将被禁用,并显示“导师”字段。然而,用户本质上能够提交他们的名字,即使他们没有键入任何东西。我只希望在用户开始键入后“回车”按钮处于活动状态

我在下面所做的似乎不起作用:(

此外,我的输入验证不起作用-知道为什么吗

class Enter_Name_Window(tk.Toplevel):
    '''A simple instruction window'''
    def __init__(self, parent):
        tk.Toplevel.__init__(self, parent)
        self.text = tk.Label(self, width=40, height=2, text= "Please enter your name and class." )
        self.text.pack(side="top", fill="both", expand=True)

        name_var = StringVar()
        def validate_enter_0():
            self.Enter_0.config(state=(NORMAL if name_var.get() else DISABLED))
            print("validate enter worked")

        name_var.trace('w', lambda name, index, mode: validate_enter_0)
        enter_name = Entry(self, textvariable=name_var)
        enter_name.pack()
        enter_name.focus_set()


        def callback():
            if len(name_var) > 10 or any(l not in string.ascii_letters for l in name_var):
                print("Input validation worked")

            self.display_name = tk.Label(self, width=40, height=2, text = "Now please enter your tutor group.")
            self.display_name.pack(side="top", fill="both", expand=True)


            tutor_var = StringVar()
            def validate_enter_2():
                self.Enter_0_2.config(state=(NORMAL if tutor_var.get() else DISABLED))
                print("validate enter worked")
            tutor_var.trace('w', lambda name, index, mode: validate_enter_0_2)
            tutor = Entry(self, textvariable=tutor_var)
            tutor.pack()
            tutor.focus_set()

            self.Enter_0.config(state="disabled")

            self.Enter_0_2 = Button(self, text="Enter", width=10, command=self.destroy)
            self.Enter_0_2.pack()


        self.Enter_0 = Button(self, text="Enter", width=10, command=callback)
        self.Enter_0.pack()

第一个明显的问题是这一行:

tutor_var.trace('w', lambda name, index, mode: validate_enter_0_2)
您创建了一个包含三个变量的函数,并将
validate\u enter\u 0\u 2
函数作为函数对象返回。这没有任何好处

您想创建一个调用
验证\u enter\u 0\u 2
函数的函数。如下所示:

tutor_var.trace('w', lambda name, index, mode: validate_enter_0_2())
您在
name\u var
中遇到了完全相同的问题,当然,您还需要在那里解决它


除此之外,您实际上没有名为
validate\u enter\u 2
的函数可调用,因为您将其定义为
validate\u enter\u 2
。这意味着您的验证函数只会引发
namererror
,而不是执行有用的操作。或者,如果您在代码中的其他地方定义了
validate\u enter\u 2
函数,它调用了错误的函数。(这是像
enter\u 0\u 2
enter\u 2
这样的神秘名称不是一件好事的原因之一。)


您的代码至少还有一个问题:您反复尝试使用
name\u var
,这是一个
StringVar
对象,就像它是一个字符串一样。您不能这样做。如果您实际查看控制台输出,Tkinter会告诉您这一点,回溯如下:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "tkval2.py", line 25, in callback
    if len(name_var) > 10 or any(l not in string.ascii_letters for l in name_var):
AttributeError: StringVar instance has no attribute '__len__'
if len(name_var.get()) > 10 or any(l not in string.ascii_letters for l in name_var.get())
def callback():
    if len(name_var.get()) > 10:
        tkMessageBox.showerror("Bad name", "Your name is too long. What's wrong with good American names like Joe?")
        name_var.set('')
        return
    # the rest of your code here
在您有机会创建新的
条目之前,就会发生该异常

要解决这个问题,您需要在
StringVar
上调用
get
,只要您想获取它的值,如下所示:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "tkval2.py", line 25, in callback
    if len(name_var) > 10 or any(l not in string.ascii_letters for l in name_var):
AttributeError: StringVar instance has no attribute '__len__'
if len(name_var.get()) > 10 or any(l not in string.ascii_letters for l in name_var.get())
def callback():
    if len(name_var.get()) > 10:
        tkMessageBox.showerror("Bad name", "Your name is too long. What's wrong with good American names like Joe?")
        name_var.set('')
        return
    # the rest of your code here

最后,正如我在回答您的另一个问题时所解释的,在某些内容发生更改之前,
跟踪
验证器不会被调用。这意味着您需要显式调用它,或者显式调用
名称变量集(“”)
,或仅禁用“关闭启动”按钮。如前所述,它将启用“关闭启动”,仅当您键入某个内容并将其删除时才禁用


我不确定这些是否是您的代码中唯一的问题,但它们肯定会阻止您的验证按预期工作。因此,您需要修复所有这些问题以及代码中的任何其他错误,然后验证才能工作


根据您的评论:

然而,我想知道如何创建一个弹出消息显示错误

你想什么时候检查?你想检查什么条件,什么时候检查

无论如何,与大多数GUI一样,“弹出”类似内容的方式是一个对话框。Tkinter书中解释了您需要了解的所有内容。但您不需要复制粘贴所有代码,也不需要从头开始编写;stdlib附带了它,它可以为您完成大部分工作。在您的情况下,您可能只需要这样做

…以及强制用户重新输入其名称的内容

如何强制他们?只需删除现有条目内容,就会留下一个空框来填充,这也会禁用按钮。这就是你想要的吗

不管怎样,猜猜你想要什么,它可能看起来像这样:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "tkval2.py", line 25, in callback
    if len(name_var) > 10 or any(l not in string.ascii_letters for l in name_var):
AttributeError: StringVar instance has no attribute '__len__'
if len(name_var.get()) > 10 or any(l not in string.ascii_letters for l in name_var.get())
def callback():
    if len(name_var.get()) > 10:
        tkMessageBox.showerror("Bad name", "Your name is too long. What's wrong with good American names like Joe?")
        name_var.set('')
        return
    # the rest of your code here
回调
函数中(键入姓名后单击按钮时调用),而不是仅仅检查某个条件并打印出某些内容,我检查一个条件并弹出一个错误对话框,清除现有名称,并提前返回,而不是创建表单的后半部分。我没有处理其他条件(任何非ASCII字母),但如何添加它应该是显而易见的

但是,这样的验证最好是通过实际验证来完成,而不是让他们等到单击按钮,然后在尝试键入第11个字符、空格或重音字符或其他您不喜欢的字符时立即捕获。然后,您可以弹出一个消息框,或者禁用按钮,直到他们修复它,然后重新启动删除/撤消更改(使用
validatecommand
函数比使用
trace
函数更容易,如我对上一个问题的回答所示)


最后一件事:与其使用消息框,不如将错误嵌入为表单本身中出现的标签(可能错误描述为红色,带有大旗图标)。这在web应用程序和更现代的GUI中很常见,因为它提供了更即时的反馈,并且对用户流的干扰更小。

这是一个后续问题,还是一个在某些方面有所不同的全新问题?(如果是后者,则在哪些方面有所不同?)另外,正如我在上一个问题上告诉你的,请提供一个-我们可以实际运行和调试的东西,而不仅仅是一段随机的代码
from Tkinter import*
import Tkinter as tk
import Tkinter
。只需执行其中一项操作,而不是全部操作,并一致使用名称。非常感谢验证和事件处理程序都能正常工作。不过,我想知道如何创建一个弹出消息,显示错误和强迫用户执行的操作重新输入他们的名字。Thanks@user3056786:这些问题有些模糊。它们看起来也像是后续问题,应该是一个或多个单独的问题。但我会编辑答案,尝试让您开始。