如何使用 python xlib 生成单个按键?
How can I use python xlib to generate a single keypress?
我想制作一个非常简单的 python 3 脚本,它将生成一个按键 (F15)。我不想使用一堆库来执行此操作,因为我只需要按下一个键,不需要支持整个键盘。我知道我需要使用 KeyPress 和 KeyRelease 来生成键盘事件。我只是不确定从哪里开始,文档有点混乱。
http://tronche.com/gui/x/xlib/events/keyboard-pointer/keyboard-pointer.html
http://python-xlib.sourceforge.net/?page=documentation
我会用 ctypes
to show you how it could work, but porting it to python-xlib
应该很简单。因此,让我们从加载库开始:
import ctypes
X11 = ctypes.CDLL("libX11.so")
并定义所需的结构:
class Display(ctypes.Structure):
""" opaque struct """
class XKeyEvent(ctypes.Structure):
_fields_ = [
('type', ctypes.c_int),
('serial', ctypes.c_ulong),
('send_event', ctypes.c_int),
('display', ctypes.POINTER(Display)),
('window', ctypes.c_ulong),
('root', ctypes.c_ulong),
('subwindow', ctypes.c_ulong),
('time', ctypes.c_ulong),
('x', ctypes.c_int),
('y', ctypes.c_int),
('x_root', ctypes.c_int),
('y_root', ctypes.c_int),
('state', ctypes.c_uint),
('keycode', ctypes.c_uint),
('same_screen', ctypes.c_int),
]
class XEvent(ctypes.Union):
_fields_ = [
('type', ctypes.c_int),
('xkey', XKeyEvent),
('pad', ctypes.c_long*24),
]
X11.XOpenDisplay.restype = ctypes.POINTER(Display)
现在我们只需要将事件发送到根window:
display = X11.XOpenDisplay(None)
key = XEvent(type=2).xkey #KeyPress
key.keycode = X11.XKeysymToKeycode(display, 0xffcc) #F15
key.window = key.root = X11.XDefaultRootWindow(display)
X11.XSendEvent(display, key.window, True, 1, ctypes.byref(key))
X11.XCloseDisplay(display)
这个最小的例子对我来说效果很好(只是使用 F2
代替)。同样可以发送 KeyRelease
事件。如果要针对特殊的window,则应适当设置key.window
。
我不确定,是否有必要使用 XEvent
联合,因为它对我来说单独使用 XKeyEvent
,但最好是安全的。
我想制作一个非常简单的 python 3 脚本,它将生成一个按键 (F15)。我不想使用一堆库来执行此操作,因为我只需要按下一个键,不需要支持整个键盘。我知道我需要使用 KeyPress 和 KeyRelease 来生成键盘事件。我只是不确定从哪里开始,文档有点混乱。
http://tronche.com/gui/x/xlib/events/keyboard-pointer/keyboard-pointer.html http://python-xlib.sourceforge.net/?page=documentation
我会用 ctypes
to show you how it could work, but porting it to python-xlib
应该很简单。因此,让我们从加载库开始:
import ctypes
X11 = ctypes.CDLL("libX11.so")
并定义所需的结构:
class Display(ctypes.Structure):
""" opaque struct """
class XKeyEvent(ctypes.Structure):
_fields_ = [
('type', ctypes.c_int),
('serial', ctypes.c_ulong),
('send_event', ctypes.c_int),
('display', ctypes.POINTER(Display)),
('window', ctypes.c_ulong),
('root', ctypes.c_ulong),
('subwindow', ctypes.c_ulong),
('time', ctypes.c_ulong),
('x', ctypes.c_int),
('y', ctypes.c_int),
('x_root', ctypes.c_int),
('y_root', ctypes.c_int),
('state', ctypes.c_uint),
('keycode', ctypes.c_uint),
('same_screen', ctypes.c_int),
]
class XEvent(ctypes.Union):
_fields_ = [
('type', ctypes.c_int),
('xkey', XKeyEvent),
('pad', ctypes.c_long*24),
]
X11.XOpenDisplay.restype = ctypes.POINTER(Display)
现在我们只需要将事件发送到根window:
display = X11.XOpenDisplay(None)
key = XEvent(type=2).xkey #KeyPress
key.keycode = X11.XKeysymToKeycode(display, 0xffcc) #F15
key.window = key.root = X11.XDefaultRootWindow(display)
X11.XSendEvent(display, key.window, True, 1, ctypes.byref(key))
X11.XCloseDisplay(display)
这个最小的例子对我来说效果很好(只是使用 F2
代替)。同样可以发送 KeyRelease
事件。如果要针对特殊的window,则应适当设置key.window
。
我不确定,是否有必要使用 XEvent
联合,因为它对我来说单独使用 XKeyEvent
,但最好是安全的。