[英]How to make pynput prevent certain keystrokes from reaching a particular application?
I want to create a tool which will allow me to use some of the Vim-style commands in an application ( Scrivener ) that does not support it.我想创建一个工具,允许我在不支持它的应用程序( Scrivener )中使用一些 Vim 风格的命令。
For example, if例如,如果
Command
mode and当前模式是Command
模式和w
,用户按下按钮w
, then, the caret should move one character to the right.然后,插入符号应该向右移动一个字符。 Instead of the w
character, Scrivener should receive the "right arrow" signal. Scrivener 应该接收“右箭头”信号,而不是w
字符。
To implement this, I wrote the following code (based on these 2 answers: 1 , 2 ):为了实现这一点,我编写了以下代码(基于这两个答案: 1 、 2 ):
from pynput.keyboard import Key, Listener, Controller
from typing import Optional
from ctypes import wintypes, windll, create_unicode_buffer
def getForegroundWindowTitle() -> Optional[str]:
hWnd = windll.user32.GetForegroundWindow()
length = windll.user32.GetWindowTextLengthW(hWnd)
buf = create_unicode_buffer(length + 1)
windll.user32.GetWindowTextW(hWnd, buf, length + 1)
if buf.value:
return buf.value
else:
return None
class State:
def __init__(self):
self.mode = "Command"
state = State()
keyboard = Controller()
def on_press(key):
pass
def on_release(key):
if key == Key.f12:
return False
window_title = getForegroundWindowTitle()
if not window_title.endswith("Scrivener"):
return
print("Mode: " + state.mode)
print('{0} release'.format(
key))
if state.mode == "Command":
print("1")
if str(key) == "'w'":
print("2")
print("w released in command mode")
# Press the backspace button to delete the w letter
keyboard.press(Key.backspace)
# Press the right arrow button
keyboard.press(Key.right)
if key == Key.insert:
if state.mode == "Command":
state.mode = "Insert"
else:
state.mode = "Command"
# Collect events until released
print("Press F12 to exit")
with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
Whenever I press the button w
in Scrivener in Command mode, two keystrokes are sent to Scrivener:每当我在命令模式下按下 Scrivener 中的按钮w
时,都会向 Scrivener 发送两次击键:
w
character.退格删除已经输入的w
字符。 This kinda works, but you can see the w
character being displayed and deleted again (see this video ).这有点工作,但您可以看到w
字符再次显示和删除(请参阅此视频)。
How can I make sure that the keystroke with w
does not reach Scrivener at all, if the mode is Command
and currently focused window is the Scrivener application?如果模式是Command
并且当前关注的 window 是 Scrivener 应用程序,我如何确保带有w
的击键根本不会到达 Scrivener?
First you need to install pyHook and pywin32 library.首先你需要安装 pyHook 和 pywin32 库。
Then monitor the keyboard information through pyhook.然后通过pyhook监听键盘信息。 If you need to intercept the keyboard information (for example, press w), return False.如果需要截取键盘信息(例如按w),返回False。
Finally, through pythoncom.PumpMessages () to achieve loop monitoring.最后通过pythoncom.PumpMessages()实现循环监控。 Here is the sample:这是示例:
import pyHook
import pythoncom
from pynput.keyboard import Key, Listener, Controller
keyboard = Controller()
def onKeyboardEvent(event):
if event.Key == "F12":
exit()
print("1")
if event.Key == 'W':
print("2")
print("w released in command mode")
# Press the right arrow button
keyboard.press(Key.right)
return False
print("hook" + event.Key)
return True
# Collect events until released
print("Press F12 to exit")
hm = pyHook.HookManager()
hm.KeyDown = onKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.