如何用Python获取触摸屏的多点触摸位置(无需Kivy)
全局多点触摸输入监听方案(无窗口)
下面分平台给出Python实现方案,和你用pynput监听鼠标的逻辑类似,能在无额外窗口的情况下捕获全屏幕的触摸位置:
Windows平台
Windows系统的触摸事件通过系统消息WM_TOUCH传递,我们可以用pywin32库创建一个隐藏的消息窗口来监听这些事件。
步骤1:安装依赖
pip install pywin32
代码实现
import win32api import win32con import win32gui import win32ui class TouchListener: def __init__(self): # 创建隐藏窗口用于接收消息 wc = win32gui.WNDCLASS() wc.lpfnWndProc = self.wnd_proc wc.lpszClassName = "TouchListenerWindow" wc.hInstance = win32api.GetModuleHandle(None) class_atom = win32gui.RegisterClass(wc) self.hwnd = win32gui.CreateWindow( class_atom, "TouchListener", 0, 0, 0, 0, 0, 0, 0, wc.hInstance, None ) # 注册触摸输入 win32gui.RegisterTouchWindow(self.hwnd, win32con.TWF_FINETOUCH) def wnd_proc(self, hwnd, msg, wparam, lparam): if msg == win32con.WM_TOUCH: # 解析触摸事件 touch_inputs = win32gui.GetTouchInputInfo(lparam) for ti in touch_inputs: # 获取触摸ID、坐标、状态 touch_id = ti.dwID x = ti.x // 100 # Windows触摸坐标单位是0.01像素,转成整数像素 y = ti.y // 100 if ti.dwFlags & win32con.TOUCHEVENTF_DOWN: print(f"触摸点 {touch_id} 按下,位置: ({x}, {y})") elif ti.dwFlags & win32con.TOUCHEVENTF_UP: print(f"触摸点 {touch_id} 抬起,位置: ({x}, {y})") elif ti.dwFlags & win32con.TOUCHEVENTF_MOVE: print(f"触摸点 {touch_id} 移动,位置: ({x}, {y})") win32gui.CloseTouchInputHandle(lparam) return 0 return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) def start(self): win32gui.PumpMessages() if __name__ == "__main__": listener = TouchListener() listener.start()
Linux平台
Linux下可以通过libinput库直接读取触摸设备的输入事件,或者解析/dev/input/event*设备文件。这里推荐用python-libinput简化开发。
步骤1:安装依赖
pip install python-libinput # 还需要系统依赖libinput-dev,以Debian/Ubuntu为例: sudo apt-get install libinput-dev
代码实现
import libinput import sys def handle_event(event): if event.type == libinput.EventType.TOUCH_DOWN: touch = event.touch print(f"触摸点 {touch.id} 按下,位置: ({touch.x}, {touch.y})") elif event.type == libinput.EventType.TOUCH_UP: touch = event.touch print(f"触摸点 {touch.id} 抬起,位置: ({touch.x}, {touch.y})") elif event.type == libinput.EventType.TOUCH_MOTION: touch = event.touch print(f"触摸点 {touch.id} 移动,位置: ({touch.x}, {touch.y})") if __name__ == "__main__": # 打开输入设备(需要root权限,或者将用户加入input组) try: udev = libinput.Udev() context = libinput.Context(udev) # 添加所有触摸设备 devices = context.path_add_device(sys.argv[1]) if len(sys.argv) > 1 else context.udev_add_all() for dev in devices: print(f"监听设备: {dev.name}") # 循环处理事件 while True: event = context.dispatch() if event: handle_event(event) except PermissionError: print("需要root权限,或者将当前用户加入input组:sudo usermod -aG input $USER")
注意:运行时需要指定触摸设备路径(比如/dev/input/event10),或者直接运行让程序自动识别,不过需要root权限或用户加入input组。
macOS平台
macOS可以通过Quartz框架的触摸事件API,用pyobjc绑定来实现全局监听。
步骤1:安装依赖
pip install pyobjc-framework-Quartz pyobjc-framework-Cocoa
代码实现
from Quartz import CGEventTapCreate, CGEventMaskBit, kCGEventTapOptionListenOnly, kCGHIDEventTap, CGEventTapEnable, CFRunLoopAddSource, CFRunLoopGetCurrent, CFMachPortCreateRunLoopSource, CFRelease from Cocoa import NSEvent, NSApp class TouchListener: def __init__(self): # 创建事件监听tap tap = CGEventTapCreate( kCGHIDEventTap, kCGEventTapOptionListenOnly, 0, CGEventMaskBit(NSEvent.NSEventTypeTouchDown) | CGEventMaskBit(NSEvent.NSEventTypeTouchUp) | CGEventMaskBit(NSEvent.NSEventTypeTouchMoved), self.handle_event, None ) if not tap: print("无法创建事件监听") exit(1) # 添加到运行循环 run_loop_source = CFMachPortCreateRunLoopSource(None, tap, 0) CFRunLoopAddSource(CFRunLoopGetCurrent(), run_loop_source, kCFRunLoopCommonModes) CGEventTapEnable(tap, True) CFRelease(run_loop_source) def handle_event(self, proxy, event_type, event, refcon): # 解析触摸事件 touch_event = NSEvent.eventWithCGEvent_(event) if touch_event: touches = touch_event.touchesMatchingPhase_inView_(NSEvent.NSTouchPhaseAny, None) for touch in touches: touch_id = touch.identity() location = touch.locationInWindow_(None) x, y = location.x, location.y phase = touch.phase() if phase == NSEvent.NSTouchPhaseBegan: print(f"触摸点 {touch_id} 按下,位置: ({x}, {y})") elif phase == NSEvent.NSTouchPhaseEnded: print(f"触摸点 {touch_id} 抬起,位置: ({x}, {y})") elif phase == NSEvent.NSTouchPhaseMoved: print(f"触摸点 {touch_id} 移动,位置: ({x}, {y})") return event if __name__ == "__main__": listener = TouchListener() NSApp.run()
注意:macOS需要在系统偏好设置的“安全性与隐私”中给终端/IDE授权“输入监控”权限,否则无法捕获全局触摸事件。
内容的提问来源于stack exchange,提问作者affect
相关产品推荐
相关产品推荐

