简体   繁体   English

Python 诅咒:让输入键终止文本框?

[英]Python curses: Make enter key terminate Textbox?

I have an application where people are asked to enter their user name and password.我有一个应用程序,要求人们输入他们的用户名和密码。 I want them to be able to just press enter to send the name and password.我希望他们能够按回车键发送名称和密码。 To do this, I've made this:为此,我做了这个:

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()

Unfortunately this doesn't work as expected.不幸的是,这不能按预期工作。 The standard character for termination (Triggered by CTRL+G) is 7 and the enter character is 10, but with the above code, all other keys are still handled correctly but when I press enter, it just gives me a newline, instead of terminating the edit mode of the Textbox.终止的标准字符(由 CTRL+G 触发)是 7,输入字符是 10,但是使用上面的代码,所有其他键仍然被正确处理,但是当我按下 Enter 时,它只是给我一个换行符,而不是终止文本框的编辑模式。 What am I doing wrong?我做错了什么?

Found this on the documentation: 在文档中找到了这个:

If validator is supplied, it must be a function.如果提供了验证器,它必须是一个函数。 It will be called for each keystroke entered with the keystroke as a parameter;每次以击键为参数输入的击键都会调用它; command dispatch is done on the result.命令调度是在结果上完成的。

So instead of running tb.do_command yourself, just return the key you want to 'input'.因此, tb.do_command自己运行tb.do_command ,只需返回您想要“输入”的键即可。

def enter_is_terminate(x):
    if x == 10:
        return 7

Also, now you don't need to define tb as a global variable, which is usually a good thing.此外,现在您不需要将tb定义为全局变量,这通常是一件好事。 :) :)


If you'd be happy with just a one line input, you wouldn't have to handle the enter key yourself.如果您只对一行输入感到满意,您就不必自己处理回车键。

On the documentation it sais this:文档上它是这样说的:

Control-J -- Terminate if the window is 1 line, otherwise insert newline. Control-J -- 如果窗口为 1 行则终止,否则插入换行符。

So if you define the textbox's sub window with line count of 1 you don't need to handle the enter key yourself.因此,如果您将文本框的子窗口定义为行数为 1,则您无需自己处理回车键。

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()

I also gave the sub a specific line and col count so the border is nicely around the textbox.我还给了sub一个特定的 line 和 col 计数,所以边框很好地围绕在文本框周围。

It helps to read the source code.它有助于阅读源代码。 Here is a working validator:这是一个有效的验证器:

def enter_is_terminate(x):
    if x == 10:
        x = 7
    return x

The validator has to return a character, which the edit function checks with do_command :验证器必须返回一个字符, edit函数用do_command检查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()

and do_command only returns 0 for the two cases (a) ASCII BEL and (b) newline on a one-line window:并且do_command仅在单行窗口上的两种情况下返回 0 (a) ASCII BEL 和 (b) 换行符:

    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)

Maybe my solution in this will help, I made a textbox that terminate by pressing enter key so do what ever u want to do with it n hv fun:-也许我在这方面的解决方案会有所帮助,我制作了一个通过按 Enter 键终止的文本框,所以做任何你想做的事 n hv fun:-

def txtpnl(stdscr, y=10, xl=10, wl=20, HIDE_WORDS = False):
    wl += xl + 2
    s = ''
    textpad.rectangle(stdscr, y, xl, y + 2, wl)
    stdscr.addstr(y + 1, xl + 1, '')
    cp = 0
    while True:
        textpad.rectangle(stdscr, y, xl, y + 2, wl)
        stdscr.addstr(y + 1, xl + 1 + cp, '')
        k = stdscr.getch()
        if k == KEY_ENTER or k in [10, 13]:
            break
        elif k == KEY_UP or k == KEY_DOWN:
            pass
        elif k == KEY_BACKSPACE or k == 8:
            if cp > 0: cp -= 1
            stdscr.addstr(y + 1, xl + 1, " " * len(s))
            s = s[:cp]+s[cp+1:]
            if HIDE_WORDS:
                stdscr.addstr(y + 1, xl + 1 + cp, "*"*len(s[cp:]))
                stdscr.addstr(y + 1, xl + 1, "*"*len(s[:cp]))
            else:
                stdscr.addstr(y + 1, xl + 1 + cp, s[cp:])
                stdscr.addstr(y + 1, xl + 1, s[:cp])

        elif k == KEY_LEFT or k == 27:
            if not cp:
                pass
            else:
                cp -= 1
                if HIDE_WORDS:
                    stdscr.addstr(y + 1, xl + 1 + cp, "*"*len(s[cp:]))
                    stdscr.addstr(y + 1, xl + 1, "*"*len(s[:cp]))
                else:
                    stdscr.addstr(y + 1, xl + 1 + cp, s[cp:])
                    stdscr.addstr(y + 1, xl + 1, s[:cp])
        elif k == KEY_RIGHT or k == 26:
            if cp == len(s):
                pass
            else:
                cp += 1
                if HIDE_WORDS:
                    stdscr.addstr(y + 1, xl + 1 + cp, "*"*len(s[cp:]))
                    stdscr.addstr(y + 1, xl + 1, "*"*len(s[:cp]))
                else:
                    stdscr.addstr(y + 1, xl + 1 + cp, s[cp:])
                    stdscr.addstr(y + 1, xl + 1, s[:cp])
        elif k in [KEY_DC, 127]:
            if HIDE_WORDS:
                stdscr.addstr(y + 1, xl + 1 + cp, "*"*len(s[cp + 1:] + " "))
                stdscr.addstr(y + 1, xl + 1, "*"*len(s[:cp]))
            else:
                stdscr.addstr(y + 1, xl + 1 + cp, s[cp + 1:] + " ")
                stdscr.addstr(y + 1, xl + 1, s[:cp])
            s = s[:cp] + s[cp + 1:]
        else:
            if len(s) < wl - xl - 2:
                if cp == len(s):
                    s += str(chr(k))
                    if HIDE_WORDS:
                        stdscr.addstr(y + 1, xl + 1, "*"*len(s))
                    else:
                        stdscr.addstr(y + 1, xl + 1, s)
                else:
                    s = s[:cp] + str(chr(k)) + s[cp:]
                    if HIDE_WORDS:
                        stdscr.addstr(y + 1, xl + 1 + len(s[:cp + 1]), "*"*len(s[cp + 1:]))
                        stdscr.addstr(y + 1, xl + 1, "*"*len(s[:cp + 1]))
                    else:
                        stdscr.addstr(y + 1, xl + 1 + len(s[:cp + 1]), s[cp + 1:])
                        stdscr.addstr(y + 1, xl + 1, s[:cp + 1])
                cp += 1
    return s

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM