我希望有一个功能类似于input()
,但在按 Esc 键时返回None
(例如)。
我尝试执行以下操作:
def input(t):
print(t)
text = ""
while True:
char = msvcrt.getche();
if char == chr(27).encode():
return None
if char == b'\r':
return text
try:
text += char.decode()
except:
pass
这在大多数情况下都有效,但是问题是,退格键不起作用,并且在按箭头键等非字符键或组合 Ctrl +时出现奇怪字符 C 。因此,getche可能不是我的问题的答案。
我以为这是一个普遍的问题,但我一直找不到解决方法。
答案 0 :(得分:1)
我使用模块keyboard
编写了代码。您使用pip install keyboard
进行安装。它读取左,右,结束,首页,输入,转义,退格键和许多其他键。
您可以使用功能read_input
。它有两个选项text
和cancel
。 text
是要打印的文本,cancel
是将取消输入的键。如果按escape
,则返回None
;如果按enter
,则键入文本。
这是代码:
def read_input(text="",cancel="esc"):
import keyboard,string as t
print(text,end="")
output = []
output2 = []
allowed = t.ascii_letters+"1234567890!@#$%^&*()-=_+{}[]|\:;',<>./?`~"+'"'
while True:
key = keyboard.read_event()
k = key.name
if key.event_type == "up":continue
if k == cancel:print("");return None
elif k == "enter":break
elif k == "end":output = output+output2;output2 = []
elif k == "home":output2 = output+output2;output = []
elif k == "left":
try:output2.insert(0,output.pop())
except:pass
elif k == "right":
try:output.append(output2.pop(0))
except:pass
elif k == "space":k = " ";output.append(k)
elif k == "backspace":output = output[:-1]
elif k in allowed:output.append(k)
foutput2 = ""
for put in output:
foutput2 += str(put)
for put in output2:
foutput2 += str(put)
for i in range(0,len(foutput2)+2):keyboard.press_and_release("backspace")
print(foutput2)
return foutput2
您可以像正常输入一样使用它:
print(read_input("Enter your name: "))
另一方面也有一些问题。
它从整个窗口读取密钥,而不仅仅是python。
在输入的第一秒(执行时)中的键可能会被忽略。
答案 1 :(得分:1)
我觉得这将是一个普遍的问题
不,不是。关于io,有两种常见的成语。首先称为面向线。它可以在批处理模式程序中使用,在该程序中,标准输入可以重定向到文件或管道。在这种模式下,程序本身甚至不应该尝试知道它是从真实的键盘还是从文件读取(或多或少,密码输入是例外)。低级驱动程序或输入库可以添加一些类似在线版本(退格处理)的功能,但是程序员不能直接访问它,并且在任何情况下都不打算可移植。
第二种模式用于GUI。在这里,大多数事情都在程序员的控制之下:输入字段在屏幕上的位置,它们的大小以及可选的特殊字符处理。更准确地说,通常是通过tkinter(tk),pyqt或pyside(Qt)或...之类的图形库进行处理。
您要求的是一种中等方法。初学者尝试探索它是很常见的,但是一段时间之后,我们都意识到,对于现实世界的程序来说,两个常见的习惯用法就足够了。
您可能会发现,从技术上讲,这个答案从技术上来说更有意义,并且从理论上讲,改进线路版本没有什么坏处,但是在实际程序中,我从来没有发现超越当前可用范围的任何真正理由。