0

我正在用 Python 和库编写一个基于文本的游戏keyboard。在我的代码中,我必须收集一个通过以下代码获得的数字:

if menu == "test":
    try:
        x = int(input("Enter a Number: "))
    except ValueError:
        print("Please input integer only...")

但是要将菜单设置为“测试”,我必须使用键盘输入 2 1 1。我的问题是,虽然菜单不是“测试”,但输入已经被收集了。运行代码时,我得到以下信息:

Enter a Number: 211

我可以在命令提示符下轻松删除 211,然后键入一些内容,但我希望它自动删除,以便我得到:

Enter a Number:

我已经尝试过的:

input().clear()

input(None)

x = 0

#import os   --at the beginning of the code

os.system("clear")
4

2 回答 2

0

我认为我的目标有点不清楚,所以我还编写了已经显示的部分之前的代码(但简化了)。

run = True
while run
   
    menu = "menu1"
    press1 = keyboard.is_pressed("1")
    press2 = keyboard.is_pressed("2")

    if menu == "menu1":
        #stuff
        if press2:                    # 2 is pressed
            menu = "menu2"

    if menu == "menu2":
        #stuff
        if press1:                    # 1 is pressed
            menu = "menu3"

    if menu == "menu3":
        #stuff
        if press1:                    # 1 is pressed
            menu = "menu4"

                                     
                                      # summed up you press 2 1 1 to get menu to "menu4"

    #now the code that was already in the question

    if menu == "menu4":
        try:
            x = int(input("Enter a Number: "))
        except ValueError:
            print("Please input integer only...")

menu4 中的输入会记住我之前输入的所有内容 (211) 但我不想要它,输入已经是 211 而不是什么都没有,因为我输入了 211 但我希望它在菜单 4 中什么都不是它不是我的试图知道我之前输入了什么。

当我运行我想要的代码时,应该会发生这种情况:

# menu = "menu1"
# programm does sth and waits for input
# user presses "2"
# menu = "menu2"
# programm does sth and waits for input
# user presses "1"
# menu = "menu3"
# programm does sth and waits for input
# user presses "1"
# menu = "menu4" 

# programm prints the following:

# Enter a Number:   <--here is a EMPTY space where you can write sth.

# Please input integer only...           #(eventually)

这不应该发生:

# programm prints the following:

# Enter a Number: 211   <--here it is NOT EMPTY

# Please input integer only...           #(eventually)
于 2020-11-07T15:13:57.983 回答
0

如果您想完全避免在终端中显示输出,您可以在 MacOS 和 Linux 上使用以下命令:

import sys
import tty
import termios

def hidden_input(*args):
    stdin = sys.stdin.fileno()
    tattr = termios.tcgetattr(stdin)
    try:
        tty.setcbreak(stdin, termios.TCSANOW)
        return input(*args)
    finally:
        termios.tcsetattr(stdin, termios.TCSANOW, tattr)

这可以通过将 TTY(99% 的时间是终端仿真器)设置为 cbreak 模式来实现。执行以下操作:

传统的“原始”模式更容易解释;它根本不对输入或输出进行内核处理。键入时立即返回所有字符,并且按原样生成所有输出。传统的“cbreak”模式用于密码输入等操作;它在输入字符时立即返回字符,不回显字符,也不进行任何内核内行编辑(这主要意味着您的程序实际上可以看到各种编辑字符)。在高层次上,'cbreak' 和 'raw' 之间有两个主要区别。首先,cbreak 保持输出处理不变,这可能相对“熟”。其次,cbreak 仍然允许您使用 ^C 中断程序,将其挂起,等等。您可以在大多数程序(例如 passwd、su、或 sudo) 要求输入密码;您可以立即用 ^C 以某种方式中断它们,例如 vi 不响应。

cbreak 的低级设置是:

  • 禁用回声;这会阻止输入的字符被回显。
  • 禁用 ICANON;这将关闭行编辑。将 VMIN 设置为 1,将 VTIME 设置为 0;这使得一旦有(至少)一个字符可用, read() 就会立即返回。

请注意,由于readline仍在使用中,您仍然可以像正常输入一样编辑行。

在 Windows 上,我不确定如何轻松做到这一点。

如果你想清除用户按下回车输入的输入,这有点困难,因为它需要部分清除已经打印的输出,这需要使用特殊的控制代码。

Windows 的一种可能更简单的解决方案:以下将清除 MacOS 和 Linux 上的整个终端,但也适用于Windows 终端(与默认的 cmd.exe 不同!)

print('\x1b[2J')

您也可以尝试通过colorama包使其与普通 Windows 终端一起使用,如 martineau 的评论中所建议的那样。

于 2020-11-07T12:57:26.010 回答