Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
阅读按键的Python方法?_Python_Windows_Key_Keydown_Getch - Fatal编程技术网

阅读按键的Python方法?

阅读按键的Python方法?,python,windows,key,keydown,getch,Python,Windows,Key,Keydown,Getch,我是Python新手,我刚刚用Python制作了一个游戏和一个菜单。 问题是,使用(raw_)input()需要我在每次按键后按enter键,我希望这样,按下向下箭头可以立即选择下一个菜单项,或者在游戏中向下移动。目前,它要求我喜欢键入“down”,然后按enter键。我也做了大量的研究,但我不希望为了实现一个keyDown()方法而下载巨大的模块(例如pygame)。有没有更简单的方法,我就是找不到 编辑: 刚刚发现msvcrt.getch()可以解决这个问题。它不是keyDown(),但它可

我是Python新手,我刚刚用Python制作了一个游戏和一个菜单。 问题是,使用(raw_)input()需要我在每次按键后按enter键,我希望这样,按下向下箭头可以立即选择下一个菜单项,或者在游戏中向下移动。目前,它要求我喜欢键入“down”,然后按enter键。我也做了大量的研究,但我不希望为了实现一个keyDown()方法而下载巨大的模块(例如pygame)。有没有更简单的方法,我就是找不到

编辑: 刚刚发现
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':
        ...
等等。。。有什么帮助吗?

请参阅MSDN文档。具体而言:

_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之前。

我自己测试了所有的东西,找到了答案。 找不到关于它的任何主题,所以我将把解决方案留在这里。这可能不是唯一的解决方案,甚至不是最好的解决方案,但它符合我的目的(在getch的限制范围内),总比什么都没有好

注意:正确的
keyDown()
,可以识别所有按键和实际按键,仍然是有价值的

解决方案:使用
ord()
-函数首先将
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()
另外,如果其他人需要,您可以从google轻松找到关键代码,或者使用python并只需按键:

from msvcrt import getch
while True:
    print(ord(getch()))

我真的不想将此作为评论发布,因为我需要评论所有答案和原始问题

所有答案似乎都依赖于MSVCRT Microsoft Visual C运行时。 如果要避免这种依赖关系,请执行以下操作:

如果需要跨平台支持,请使用以下库:

可以考虑更优雅的解决方案

代码示例:

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)

我也在努力做到这一点。从上面的代码中,我了解到可以多次调用getch()函数,以便从函数中获取两个字节。因此,如果您只是想使用byte对象,就不需要ord()函数

while True :
    if m.kbhit() :
        k = m.getch()
        if b'\r' == 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中按enter键之前,此代码将用于打印任何键 (我使用的是VS代码)
如果需要,您可以在if中自定义特定键

现在已经很晚了,但我制作了一个适用于Windows、Mac和Linux的快速脚本,只需使用每个命令行:

导入操作系统、平台
def close():
如果platform.system()=“Windows”:
打印(“按任意键退出…”)
操作系统(“暂停>nul”)
退出()
elif platform.system()=“Linux”:
系统(“read-n1-r-p\”按任意键退出…\“键”)
退出()
elif platform.system()=“达尔文”:
打印(“按任意键退出…”)
系统(“read-n1-s-p\”)
退出()
其他:
退出()

它只使用内置函数,应该适用于这三种功能(尽管我只测试了Windows和Linux…。

不是它的副本。这是关于按键事件,而不是单字符输入。我可以haz跨平台解决方案
msvcrt
在PythonWell的mac/linux发行版上不可用,我现在已经找到了,但无法发布最终的解决方案。但是这个+ord()+char()我正在使用上面的代码,但是我的代码只是在getch()处阻塞,然后什么也没有发生。有什么帮助吗?@AnumSheraz上述方法仅在您从命令提示符运行代码时有效。如果您首先将字符转换为字节,则可以直接与keypressed'keypressed==bytes('q','utf-8')进行比较,检查是否按了q。它适用于enter或esc等特殊键,但您需要知道这些键的代码(例如esc为“\x1b”),请在回答中添加一些解释来解释代码。为什么在按箭头键时必须执行另一个key=ord(getch())操作?第一次,你会得到一个224,但是它会马上得到正确的密码。如何安装?当内置模块(msvcrt)工作正常时,安装特殊库(“getkey”)是一个非常无效的解决方案@Apostolos正如他在解决方案中所说,msvcrt只在Windows上可用,getkey是跨平台的。我明白你的意思。但请想一想:由于每个平台都有自己的内置“getkey”模块(在Windows中称为“msvcrt”),因此安装额外的“getkey”模块永远是无用的(简单逻辑)
while True :
    if m.kbhit() :
        k = m.getch()
        if b'\r' == 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='')