如何在Python中获取键代码

如何在Python中获取键代码,python,input,keycode,Python,Input,Keycode,我必须知道按下了什么键,但不需要字符的代码,我想知道某人何时按下“A”键,即使获得的键是“A”或“A”,其他所有键也是如此 我不能使用PyGame或任何其他库(包括Tkinter)。只有Python标准库。这必须在终端上完成,而不是在图形界面上 不需要字符代码。我需要知道密码 例: 根据您试图实现的目标,可能使用一个库,例如,可以实现您想要的功能。Pygame包含比Python标准库通常提供的更高级的按键处理功能。您可能必须使用它,它是“标准”Python gui,多年来一直包含在Python中

我必须知道按下了什么键,但不需要字符的代码,我想知道某人何时按下“A”键,即使获得的键是“A”或“A”,其他所有键也是如此

我不能使用PyGame或任何其他库(包括Tkinter)。只有Python标准库。这必须在终端上完成,而不是在图形界面上

不需要字符代码。我需要知道密码

例:


根据您试图实现的目标,可能使用一个库,例如,可以实现您想要的功能。Pygame包含比Python标准库通常提供的更高级的按键处理功能。

您可能必须使用它,它是“标准”Python gui,多年来一直包含在Python中

由于数据进出命令行进程的方式,命令行解决方案可能不可用。GUI程序(某种风格或另一种风格)都通过(可能是库包装的)事件流接收用户输入。每个事件都将记录事件的详细信息。对于击键事件,记录可能包含某些编码中的任何键码、修改器键位字段或文本字符。哪些字段及其命名方式取决于所调用的事件库

命令行程序通过字符流接收用户输入。无法捕获较低级别的数据。正如myroslav在他的文章中解释的那样,tty可以处于煮熟模式或未煮熟模式,唯一的区别是,在煮熟模式下,终端将为您处理(一些)控制字符,如delete和enter,以便该过程接收输入行,而不是一次一个字符


处理任何低于此值的操作都需要(依赖于操作系统)系统调用或在/dev中打开字符设备。Python的标准库对此没有提供标准功能。

如果您只需要在windows中工作,您应该尝试。

请参阅标准模块。它允许从默认的面向行(cooke)模式切换到面向字符(cbreak)模式。从sys.stdin读取单个字符将导致下一个按下的键盘键(如果它生成代码):

注意:解决方案仅适用于Unix(包括Linux)

编辑:在Windows上尝试//我没有地方去尝试


编辑2:通过(请参阅)使用带有
ReadConsoleInput
函数的win32低级控制台API。您应该过滤掉按键-
e.EventType==KEY\u EVENT
并查找
e.EVENT.KeyEvent.wVirtualKeyCode
值。应用程序示例(不是Python,只是想了解一下)可以在上找到。

显而易见的答案:

someFunction = string.upper

ord('a') != ord('A')                      # 97 != 65
someFunction('a') == someFunction('A')    # a_code == A_code
或者,换言之(关键词):

等等

下面是getch函数的一个实现,它可以在Windows和Linux平台上工作:


此函数将返回大写字符的代码:

def upCcode( ch ):
    if(len(ch) == 1):
        return ord(ch.upper())
这是小写字符代码:

def lowCcode( ch ):
        if(len(ch) == 1):
            return ord(ch.lower())
这种方法简单得多,而且您不需要导入外部库

您需要从两种方法中选择一种作为您在问题中描述的“someFunction”。下面是一个例子:

输出:

# when using upCode():
>> upCcode('a')
65

>> upCcode('A')
65

# when using lowCode():
>> lowCcode('a')
97

>> lowCcode('A')
97
看看Python中的模块。它还有一个很好的用途,您可以轻松地为代码创建键盘侦听器

听众的官方例子是:

from pynput.keyboard import Key, Listener

def on_press(key):
    print('{0} pressed'.format(
        key))

def on_release(key):
    print('{0} release'.format(
        key))
    if key == Key.esc:
        # Stop listener
        return False

# Collect events until released
with Listener(on_press=on_press,
              on_release=on_release) as listener:
    listener.join()

希望这能有所帮助。

这是我最近一直在努力解决的一个话题。 这里要检查的另一件事是,您是否在不同的键盘布局中获得了正确的值。例如,当您切换到法式PC布局时,pygame报告的数字键代码看起来不正确。我的建议是使用wxPython。它在RawKeyCode属性中公开平台特定的密钥代码。 下面是一个代码示例,它演示了:

import logging as log
import wx

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(200,100))

        self.panel = wx.Panel(self, wx.ID_ANY)
        self.panel.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        self.panel.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
        self.panel.Bind(wx.EVT_CHAR, self.OnKeyDown)
        self.panel.SetFocus()
        self.Show(True)

    def OnKeyDown(self, event=None):
        line_txt = '---------------------'
        print(line_txt)
        for var in ['RawKeyCode', 'KeyCode', 'UnicodeKey']:
            print(var, getattr(event, var))
            if var == 'UnicodeKey':
                print('char', chr(getattr(event, var)))
        print(line_txt)


if __name__ == "__main__":
    app = wx.App(False)
    gui = MainWindow(None, "test")
    app.MainLoop()
例如,当我在mac上按fn键(仅mac键)时,我会看到以下记录:

---------------------
RawKeyCode 63
KeyCode 0
UnicodeKey 0
char 
---------------------

这与.

一致,谢谢,但我不必使用标准python库以外的任何其他库。好的。我将这个答案留在这里(而不是删除它)因为它可能对来这里问类似问题的其他人有用。对于否决这一点的人来说:最初的问题并没有说明pygame是不可接受的。+1表示切题帮助:SO的主要优势之一。图形或终端用户界面?Windows或Linux?请更新问题,而不是添加另一条注释。请使用“编辑”标记更新问题,以显示增强的问题。TKinter是标准python库的一部分。python已经提供了很多年了。我有一个类似的问题,你能帮我一下吗:重复,我不需要字符代码,我需要按键代码,按键a或SHIFT+a必须是相同的。使用ord()将返回一个带A的值和另一个带SHIFT+A的值;而像箭头这样的键是不会起作用的,我认为你问的问题太低了。它在DOS中是有效的。现在的操作系统采用从键到符号的键映射方法,使得切换键盘布局(语言)变得容易,因此很少有机会使用低级按键。pygame解决了这个问题。除了我在笔记本电脑上发现的一些问题外,代码运行良好。1.CTRL+J=10和CTRL+M=10。他们是一样的,我不知道为什么。2.CTRL+some char与CTRL+ALT+some char相同。在macOS上,这不会打印fn、控件、选项和命令的结果。如果您需要这些关键代码,请参阅下面我的wxPython答案。仅供参考,此库在MacOD上无法正常工作,因为它们的文档在控制台中无法工作:“请确保您有一台X服务器正在运行,并且显示环境变量设置正确”
# when using upCode():
>> upCcode('a')
65

>> upCcode('A')
65

# when using lowCode():
>> lowCcode('a')
97

>> lowCcode('A')
97
from pynput.keyboard import Key, Listener

def on_press(key):
    print('{0} pressed'.format(
        key))

def on_release(key):
    print('{0} release'.format(
        key))
    if key == Key.esc:
        # Stop listener
        return False

# Collect events until released
with Listener(on_press=on_press,
              on_release=on_release) as listener:
    listener.join()
import logging as log
import wx

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(200,100))

        self.panel = wx.Panel(self, wx.ID_ANY)
        self.panel.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        self.panel.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
        self.panel.Bind(wx.EVT_CHAR, self.OnKeyDown)
        self.panel.SetFocus()
        self.Show(True)

    def OnKeyDown(self, event=None):
        line_txt = '---------------------'
        print(line_txt)
        for var in ['RawKeyCode', 'KeyCode', 'UnicodeKey']:
            print(var, getattr(event, var))
            if var == 'UnicodeKey':
                print('char', chr(getattr(event, var)))
        print(line_txt)


if __name__ == "__main__":
    app = wx.App(False)
    gui = MainWindow(None, "test")
    app.MainLoop()
---------------------
RawKeyCode 63
KeyCode 0
UnicodeKey 0
char 
---------------------