在 linux 机器上检测 python 3 中按键的最简单方法是什么?

新手上路,请多包涵

现在我正在尝试用树莓派和 makey makey 编写一个小代码。 makey makey 是一块小板,当某些触点通电时可充当 USB 键盘。我的问题是在 python 脚本中检测这些按键的最简单方法是什么。我知道使用 GPIO 引脚会更容易,但现在我正在寻找这个。我已经看到了一些例子,例如使用 msvcrt 中的 getch()(据我了解,它仅适用于 Windows)、使用 pygame.key 和使用 getKey。哪一个论文最容易使用?有没有什么可以检测到按下一个键和释放一个键?

伪代码:

 import whatever needs importing

if the "W" key is pressed:
   print ("You pressed W")

elif the "S" is pressed:
    print ("You pressed S")

等等。谢谢。

原文由 montainz09 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 601
2 个回答

这是一个简单的循环,它将 stdin 置于原始模式(禁用缓冲,因此您不必按 enter 键)以获取单个字符。你应该做一些更聪明的事情(比如 with 声明来禁用它)但是你在这里明白了:

 import tty
import sys
import termios

orig_settings = termios.tcgetattr(sys.stdin)

tty.setcbreak(sys.stdin)
x = 0
while x != chr(27): # ESC
    x=sys.stdin.read(1)[0]
    print("You pressed", x)

termios.tcsetattr(sys.stdin, termios.TCSADRAIN, orig_settings)

我认为您必须循环检测 Python 中的密钥发布。

ETA 一些更多的解释:

在 Linux 上,程序的输入将被 行缓冲。这意味着操作系统将缓冲输入直到它有整行,所以你的程序甚至不会看到用户键入的任何内容,直到用户也点击“输入”。换句话说,如果您的程序期望用户键入“w”并且用户执行了此操作,则“w”将位于操作系统的缓冲区中,直到用户点击“enter”。此时整行都被传送到您的程序,因此您将获得字符串“w\n”作为用户的输入。

您可以通过将 tty 置于 原始模式 来禁用它。您使用 Python 函数 tty.setcbreak 执行此操作,它将调用 linux 中的 tty 驱动程序以告诉它停止缓冲。我将 sys.stdin 参数传递给它,告诉它我想为1关闭哪个流的缓冲。所以在 tty.setcbreak 调用之后,上面的循环将为您提供用户按下的每个键的输出。

但是,一个复杂的问题是,一旦您的程序退出,tty 仍处于原始模式。您通常会发现这并不令人满意,因为您没有获得现代终端设置提供的任何功能(例如当您使用控制或转义序列时)。例如,请注意您可能无法使用 ctrl-C 退出程序。因此,您应该在读取完输入字符后将终端重新置于 熟化模式termios.tcsetattr 电话只是说“把终端放回我找到它的地方”。它知道如何通过首先调用 termios.tcgetattr 在程序开头说“告诉我终端的所有当前设置”来做到这一点。

一旦理解了所有这些,您应该能够轻松地将功能封装在适合您的程序的函数中。

1 stdin 是用户输入的流。 Wikipedia 可以告诉您更多关于 标准流 的信息。

原文由 Turn 发布,翻译遵循 CC BY-SA 4.0 许可协议

使用一个好的轻量级模块 curtsies 你可以做这样的事情(取自他们的 examples/ 目录):

 from curtsies import Input

def main():
    with Input(keynames='curses') as input_generator:
        for e in input_generator:
            print(repr(e))

if __name__ == '__main__':
    main()

所以按下键盘上的键会给你这样的东西:

 'a'
's'
'KEY_F(1)'
'KEY_F(2)'
'KEY_F(3)'
'KEY_F(4)'
'KEY_F(5)'
'KEY_LEFT'
'KEY_DOWN'
'KEY_UP'
'KEY_RIGHT'
'KEY_NPAGE'
'\n'

bpython 使用 curtsies 作为终端相关内容的低级抽象。

解码输入的基本问题是,在不同的终端和终端仿真器程序中,例如 xtermgnome-terminals 物理上相同的键会产生不同的键码序列。这就是为什么需要知道应该使用哪些终端设置来解码输入的原因。这样的模块有助于从那些血淋淋的细节中抽象出来。

原文由 user3159253 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题