我必须知道按下了什么键,但不需要字符的代码,我想知道有人按下'A'键,即使获得的键是'a'或'A',所以所有其他钥匙。
我不能使用PyGame或任何其他库(包括Tkinter)。只有Python标准库。这必须在终端中完成,而不是图形界面。
不需要字符代码。我需要知道关键代码。
例如:
ord('a') != ord('A') # 97 != 65
someFunction('a') == someFunction('A') # a_code == A_code
答案 0 :(得分:20)
请参阅tty标准模块。它允许使用tty.setcbreak(sys.stdin)从默认的面向行(煮熟)模式切换到面向字符的(cbreak)模式。从sys.stdin中读取单个字符将导致下一个按下的键盘键(如果它生成代码):
import sys
import tty
tty.setcbreak(sys.stdin)
while True:
print ord(sys.stdin.read(1))
注意:解决方案仅限于Unix(包括Linux)。
修改:在Windows上尝试msvcrt.getche() / getwche()。 /我无处可试......
编辑2:通过ctypes.windll使用win32低级控制台API(请参阅example at SO)并使用ReadConsoleInput
功能。您应该过滤掉按键 - e.EventType==KEY_EVENT
并查找e.Event.KeyEvent.wVirtualKeyCode
值。可以在http://www.benryves.com/tutorials/?t=winconsole&c=4找到应用程序示例(不是在Python中,只是为了获得一个想法)。
答案 1 :(得分:9)
根据您要完成的任务,可能使用pygame之类的库可以满足您的需求。 Pygame包含比Python标准库通常提供的更高级的按键处理。
答案 2 :(得分:3)
您可能必须使用Tkinter,这是'标准'Python gui,并且已经包含在python中多年。
由于数据传入和传出命令行进程的方式,命令行解决方案可能不可用。 GUI程序(某些风格或其他)都通过(可能是库包装的)事件流接收用户输入。每个活动都将记录活动的详细信息。对于击键事件,记录可能包含某些编码中的任何键码,修饰键位域或文本字符。哪些字段及其命名方式取决于您调用的事件库。
命令行程序通过字符流接收用户输入。无法捕获较低级别的数据。正如myroslav在帖子中解释的那样,tty可以处于熟或未烹饪模式,唯一的区别是在熟模式下终端将为您处理(某些)控制字符,如删除和输入,以便进程接收输入行,而不是每次1个字符。
处理低于此要求的任何内容(需要依赖于OS)系统调用或在/ dev中打开字符设备。 Python的标准库没有为此提供标准工具。
答案 3 :(得分:0)
如果您只需要在Windows中工作,则应尝试msvcrt。
答案 4 :(得分:0)
显而易见的答案:
someFunction = string.upper
ord('a') != ord('A') # 97 != 65
someFunction('a') == someFunction('A') # a_code == A_code
或其他(关键)词:
char_from_user = getch().upper() # read a char converting to uppercase
if char == 'Q':
# quit
exit = True # or something
elif char in ['A', 'K']:
do_something()
等...
这是getch函数的一个实现,它可以在Windows和Linux平台上运行,based on this recipe:
class _Getch(object):
"""Gets a single character from standard input.
Does not echo to the screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
def __call__(self):
return self.impl()
class _GetchUnix(object):
def __init__(self):
import tty, sys
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows(object):
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
getch = _Getch()
答案 5 :(得分:0)
此函数将返回大写字符的代码:
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
答案 6 :(得分:0)
在Python中查看pynput模块。它还有一个很好的tutorial使用,你可以轻松地为你的代码创建键盘监听器。
听众的官方例子是:
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()
希望这有帮助。
答案 7 :(得分:0)
这是我最近一直在努力的话题。 这里要检查的另一件事是,您是否在不同的键盘布局中获得正确的值。例如,当您切换到法语-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
---------------------