用于读取按键的 Python 方法?
- 2025-03-21 09:07:00
- admin 原创
- 41
问题描述:
我是 Python 新手,我刚刚用 Python 制作了一个游戏和一个菜单。问题是,使用 (raw_)input() 要求我在每次按键后按 Enter 键,我想这样按下向下箭头就会立即选择下一个菜单项,或者在游戏中向下移动。目前,它要求我输入“down”,然后按 Enter 键。我也做了相当多的研究,但我不想下载巨大的模块(例如 pygame)只是为了实现一个 keyDown() 方法。那么有没有更简单的方法,我只是找不到?
编辑:
刚刚发现这msvcrt.getch()
可以解决问题。它不是 keyDown(),但它有效。但是,我也不确定如何使用它,它看起来很奇怪,有什么帮助吗?这是我目前得到的结果:
from msvcrt import getch
while True:
key = getch()
print(key)
但是,它一直给我这些无意义的字节,例如,向下箭头是这样的:
b'xe0'
b'P'
我不知道如何使用它们,我尝试过与 chr() 进行比较,甚至使用 ord(),但实际上无法进行任何比较。我尝试做的基本上是这样的:
from msvcrt import getch
while True:
key = getch()
if key == escape:
break
elif key == downarrow:
movedown()
elif key == 'a':
...
等等...有什么帮助吗?
解决方案 1:
我通过自己测试所有东西找到了答案。但是找不到任何相关主题,所以我就把解决方案留在这里。这可能不是唯一的解决方案,甚至不是最好的解决方案,但它对我的目的有用(在 getch 的限制范围内),总比没有好。
注意:keyDown()
能够识别所有按键和实际按键的正确方法仍然很有价值。
解决方案:ord()
首先使用-function 将 转换getch()
为整数(我猜它们是虚拟键代码,但不太确定)效果很好,然后将结果与代表所需键的实际数字进行比较。此外,如果需要,我可以在chr()
返回的数字周围添加一个额外的数字,以便将其转换为字符。但是,我主要使用向下箭头、esc 等,因此将它们转换为字符是愚蠢的。这是最终的代码:
from msvcrt import getch
while True:
key = ord(getch())
if key == 27: #ESC
break
elif key == 13: #Enter
select()
elif key == 224: #Special keys (arrows, f keys, ins, del, etc.)
key = ord(getch())
if key == 80: #Down arrow
moveDown()
elif key == 72: #Up arrow
moveUp()
此外,如果其他人需要,您可以轻松地从谷歌中找出键代码,或者通过使用 python 并按下键:
from msvcrt import getch
while True:
print(ord(getch()))
解决方案 2:
请参阅 MSDN getch文档。具体来说:
_getch 和 _getwch 函数从控制台读取单个字符而不回显该字符。这些函数均不能用于读取 CTRL+C。读取功能键或箭头键时,必须调用每个函数两次;第一次调用返回 0 或 0xE0,第二次调用返回实际的键代码。
Python 函数返回一个字符。您可以使用它ord()
来获取可以测试的整数值,例如keycode = ord(msvcrt.getch())
。
因此,如果您读取了 0x00 或 0xE0,请再次读取它以获取箭头或功能键的键代码。根据实验,0x00 位于 F1-F10(0x3B-0x44)之前,而 0xE0 位于箭头键和 Ins/Del/Home/End/PageUp/PageDown 之前。
解决方案 3:
我真的不想将其作为评论发布,因为我需要对所有答案和原始问题进行评论。
所有答案似乎都依赖于 MSVCRT Microsoft Visual C Runtime。如果您想避免这种依赖关系:
如果您需要跨平台支持,请使用此处的库:
https://pypi.org/project/getkey/#files
https://github.com/kcsaff/getkey
可以提供更优雅的解决方案。
代码示例:
from getkey import getkey, keys
key = getkey()
if key == keys.UP:
... # Handle the UP key
elif key == keys.DOWN:
... # Handle the DOWN key
elif key == 'a':
... # Handle the `a` key
elif key == 'Y':
... # Handle `shift-y`
else:
# Handle other text characters
buffer += key
print(buffer)
解决方案 4:
from msvcrt import getch
pos = [0, 0]
def fright():
global pos
pos[0] += 1
def fleft():
global pos
pos[0] -= 1
def fup():
global pos
pos[1] += 1
def fdown():
global pos
pos[1] -= 1
while True:
print'Distance from zero: ', pos
key = ord(getch())
if key == 27: #ESC
break
elif key == 13: #Enter
print('selected')
elif key == 32: #Space
print('jump')
elif key == 224: #Special keys (arrows, f keys, ins, del, etc.)
key = ord(getch())
if key == 80: #Down arrow
print('down')
fdown
elif key == 72: #Up arrow
print('up')
fup()
elif key == 75: #Left arrow
print('left')
fleft()
elif key == 77: #Right arrow
print('right')
fright()
解决方案 5:
我也试图实现这一点。从上面的代码中,我理解的是,您可以多次调用 getch() 函数,以便从该函数中获取两个字节。因此,如果您只是想与字节对象一起使用,则 ord() 函数不是必需的。
while True :
if m.kbhit() :
k = m.getch()
if b'
' == k :
break
elif k == b'x08'or k == b'x1b':
# b'x08' => BACKSPACE
# b'x1b' => ESC
pass
elif k == b'xe0' or k == b'x00':
k = m.getch()
if k in [b'H',b'M',b'K',b'P',b'S',b'x08']:
# b'H' => UP ARROW
# b'M' => RIGHT ARROW
# b'K' => LEFT ARROW
# b'P' => DOWN ARROW
# b'S' => DELETE
pass
else:
print(k.decode(),end='')
else:
print(k.decode(),end='')
此代码将打印任意键,直到在 CMD 或 IDE 中按下回车键(我使用的是 VS CODE)如果需要,您可以在 if 中自定义特定键
解决方案 6:
现在真的很晚了,但是我制作了一个适用于 Windows、Mac 和 Linux 的快速脚本,只需使用每个命令行即可:
import os, platform
def close():
if platform.system() == "Windows":
print("Press any key to exit . . .")
os.system("pause>nul")
exit()
elif platform.system() == "Linux":
os.system("read -n1 -r -p \"Press any key to exit . . .\" key")
exit()
elif platform.system() == "Darwin":
print("Press any key to exit . . .")
os.system("read -n 1 -s -p \"\"")
exit()
else:
exit()
它仅使用内置函数,并且适用于所有三个(尽管我只测试了 Windows 和 Linux...)。
解决方案 7:
我建议使用 BoppreH 的键盘模块。此示例展示了如何以非阻塞方式检测 Python 控制台之外的按键。当您按下 f 键时,它会调用一个打印一些文本的函数。要结束脚本的执行,请按 q 键。有关更多信息和特殊键代码,请单击此处
import keyboard
def my_function():
print("button pressed")
def my_quit():
global mybool
mybool = False
keyboard.add_hotkey('f', my_function)
keyboard.add_hotkey('q', my_quit)
mybool = True
while mybool:
keyboard.read_key()
如果你想暂停脚本的执行,请add_hotkey()
使用keyboard.wait('esc')
扫码咨询,免费领取项目管理大礼包!