私は通常のキーボードでキーコードを実装したいと思っています。 これがプログラムを動作させるには、すべてのキーイベントをグローバルに呑み込んで、後でそれらを通過させなければなりません。python xlibでkeyeventsをグローバルにキャプチャ、無視、送信し、偽の入力を認識
私の現在のテストは "1"キーをつかんでいます。このキーを押すと、xtest.fake_inputを介してフォーカスされたウィンドウに「x」を送信するハンドラが呼び出されます。私は "1"キーをつかむだけなので、問題はないはずですよね? "x"が押されたため、何とかハンドラが再び呼び出されます。実際には、私が入力する "1"の瞬間に、プログラムはすべての鍵を聴いています。 がこのイベントを処理した後
display.allow_events(X.ReplayKeyboard, X.CurrentTime)
を呼び出すこととは何かを持っている可能性がありますが、私はこれをしない場合、すべてがフリーズします。
最後のプログラムでは、リスニング動作の変更は実際には関係ありませんが、私はユーザーイベントから偽のイベントを区別することができなければなりません。これを行うには、私はdisplay.next_event()を素早く転送していますが、ユーザが正確な時刻に入力している可能性があり、それらのキーストロークが失われる可能性があるため、これは理想的ではありません。
私は
display.flush()
display.sync()
経由のEventQueueを送信し、空の間にkeygrabを解放しようとしたが、それは何もしません。
だから、どのように偽の入力イベントを認識したり無視したりするのか、なぜ私は突然すべてのキー押し(そしてリリース)を聞いているのですか?
xlibは非常にイライラです。
from Xlib.display import Display
import Xlib
from Xlib import X
import Xlib.XK
import sys
import signal
display = None
root = None
def handle_event(aEvent):
print "handle!"
send_key("x")
def send_key(emulated_key):
global display,root
print "send key"
# ungrabbing doesnt help
root.ungrab_key(10,X.AnyModifier)
window = display.get_input_focus()._data["focus"]
# Generate the correct keycode
keysym = Xlib.XK.string_to_keysym(emulated_key)
keycode = display.keysym_to_keycode(keysym)
# Send a fake keypress via xtestaaa
Xlib.ext.xtest.fake_input(window, Xlib.X.KeyPress, keycode)
Xlib.ext.xtest.fake_input(window, Xlib.X.KeyRelease, keycode)
display.flush()
display.sync()
# fast forward those two events,this seems a bit hacky,
# what if theres another keyevent coming in at that exact time?
while display.pending_events():
display.next_event()
#
root.grab_key(10, X.AnyModifier, True,X.GrabModeSync, X.GrabModeSync)
def main():
# current display
global display,root
display = Display()
root = display.screen().root
# we tell the X server we want to catch keyPress event
root.change_attributes(event_mask = X.KeyPressMask)
# just grab the "1"-key for now
root.grab_key(10, X.AnyModifier, True,X.GrabModeSync, X.GrabModeSync)
# while experimenting everything could freeze, so exit after 10 seconds
signal.signal(signal.SIGALRM, lambda a,b:sys.exit(1))
signal.alarm(10)
while 1:
event = display.next_event()
print "event"
#if i dont call this, the whole thing freezes
display.allow_events(X.ReplayKeyboard, X.CurrentTime)
handle_event(event)
if __name__ == '__main__':
main()
これは、しばらくしてから、またはキーの繰り返しで他のキーをマッシュした後、黙ってクラッシュするように見えます。別のユーザーもこれを報告しましたが、彼のコメントは回答として投稿されたため削除されました。 – ninjagecko
@ ninjagecko私は同じ問題があります。私もどのキーの組み合わせを把握していない。しかし、20分後、1分半後には失敗しました。ランダム/キーボード/マウスの使用に依存しているようです。 – Munchhausen