windows 阅读按键的Python方法?

vhipe2zx  于 2022-12-14  发布在  Windows
关注(0)|答案(7)|浏览(165)

我刚用Python做了一个游戏和一个菜单(raw_)输入()要求我每次按键后都要按回车键,我想让它按下向下箭头就可以立即选择下一个菜单项,或者在游戏中向下移动。目前,它要求我像键入“向下”然后按回车键。我也做了相当多的研究,但是我不想下载巨大的模块(例如pygame)来实现一个keyDown()方法。那么有没有更简单的方法,我只是找不到?

**Edit:**刚刚发现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':
        ...

等等......有什么帮助吗?

holgip5t

holgip5t1#

我自己测试了所有的东西才发现的。找不到任何关于它的主题,所以我就把解决方案留在这里了。这可能不是唯一的,甚至不是最好的解决方案,但它对我的目的(在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()

另外,如果其他人需要,你可以很容易地找到从谷歌的键码,或通过使用python,只是按下键:

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

ymdaylpp2#

请参见MSDN getch文档。具体内容包括:
_getch和_getwch函数从控制台读取一个字符而不回显该字符。这些函数都不能用于读取CTRL+C。当阅读功能键或箭头键时,每个函数必须调用两次;第一个调用返回0或0xE 0,第二个调用返回实际的键控代码。
Python函数返回一个字符。您可以使用ord()来获取一个可以测试的整数值,例如keycode = ord(msvcrt.getch())
因此,如果您读取0x 00或0xE 0,请再次读取它以获取箭头键或功能键的键码。根据实验,0x 00位于F1-F10(0x 3B-0x 44)之前,0xE 0位于箭头键和Ins/Del/Home/End/PageUp/PageDown之前。

hlswsv35

hlswsv353#

我真的不想张贴这作为一个评论,因为我需要评论所有的答案和原来的问题。
所有的答案似乎都依赖于MSVCRT Microsoft Visual C运行时。如果您希望避免这种依赖性:
如果您需要跨平台支持,请使用下面的库:
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)
scyqe7ek

scyqe7ek4#

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

kcrjzv8t5#

我也在尝试实现这一点。从上面的代码中,我理解的是,你可以多次调用getch()函数,以便从函数中获得两个字节。所以,如果你只是想使用字节对象,那么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(我使用VS代码)如果需要,您可以自定义内部如果特定的键

pwuypxnk

pwuypxnk6#

现在真的很晚了,但我做了一个快速的脚本,适用于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...)。

xjreopfe

xjreopfe7#

我建议使用BoppreH的键盘模块。这个例子展示了如何以一种非阻塞的方式检测python控制台之外的按键。当你按下f键时,它会调用一个打印一些文本的函数。要结束脚本的执行,请按下q键。要了解更多信息和特殊的键码,请单击here

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()的脚本intsead,请使用keyboard.wait('esc')

相关问题