Python诅咒:使Enter键终止Textbox吗?

Flo*_*lar 2 python curses ncurses python-curses

我有一个要求人们输入用户名和密码的应用程序。我希望他们能够仅按Enter键即可发送名称和密码。为此,我做到了:

import curses, curses.textpad
def setup_input():
    inp = curses.newwin(8,55, 0,0)
    inp.addstr(1,1, "Please enter your username:")
    sub = inp.subwin(2,1)
    sub.border()
    sub2 = sub.subwin(3,2)
    global tb
    tb = curses.textpad.Textbox(sub2)
    inp.refresh()
    tb.edit(enter_is_terminate)

def enter_is_terminate(x):
    if x == 10:
        tb.do_command(7)
    tb.do_command(x)

setup_input()
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不能按预期工作。终止的标准字符(由CTRL + G触发)为7,输入字符为10,但是使用上面的代码,所有其他键仍然可以正确处理,但是当我按Enter键时,它只是给我换行符,而不是终止文本框的编辑模式。我究竟做错了什么?

Tho*_*key 6

它有助于阅读源代码。这是一个有效的验证器:

def enter_is_terminate(x):
    if x == 10:
        x = 7
    return x
Run Code Online (Sandbox Code Playgroud)

验证器必须返回一个字符,edit函数将使用以下字符进行检查do_command

def edit(self, validate=None):
    "Edit in the widget window and collect the results."
    while 1:            
        ch = self.win.getch()
        if validate:  
            ch = validate(ch)
        if not ch:      
            continue
        if not self.do_command(ch):
            break             
        self.win.refresh() 
    return self.gather()
Run Code Online (Sandbox Code Playgroud)

并且do_command在两种情况下(a)ASCII BEL和(b)单行窗口上的换行符仅返回0:

    elif ch == curses.ascii.BEL:                           # ^g
        return 0
    elif ch == curses.ascii.NL:                            # ^j
        if self.maxy == 0:
            return 0
        elif y < self.maxy:
            self.win.move(y+1, 0)
Run Code Online (Sandbox Code Playgroud)


Sev*_*eri 5

在文档中找到了这一点:

如果提供了验证器,则它必须是一个函数。对于以击键作为参数输入的每个击键,都会调用该方法;命令分派是根据结果完成的。

因此,不要tb.do_command自己运行,只需返回要“输入”的键即可。

def enter_is_terminate(x):
    if x == 10:
        return 7
Run Code Online (Sandbox Code Playgroud)

另外,现在您不需要定义tb为全局变量,这通常是一件好事。:)


如果只用一行输入就可以满意,那么您就不必自己处理Enter键。

文档中说:

Control-J-如果窗口为1行则终止,否则插入换行符。

因此,如果您以行数1定义文本框的子窗口,则无需自己处理Enter键。

def setup_input():
    inp = curses.newwin(8,55, 0,0)
    inp.addstr(1,1, "Please enter your username:")
    sub = inp.subwin(3, 41, 2, 1)
    sub.border()
    sub2 = sub.subwin(1, 40, 3, 2)
    tb = curses.textpad.Textbox(sub2)
    inp.refresh()
    tb.edit()
Run Code Online (Sandbox Code Playgroud)

我还指定sub了特定的行数和列数,因此边框很好地围绕了文本框。