使用evdev模拟触摸输入报错,寻求技术解决方案
Hey there! Let's break down why your touch emulation code is failing and get it working properly. The main issues are incomplete device capabilities and missing required touch-specific events. Here's how to fix it step by step:
Key Issues in Your Original Code
Missing Multi-Touch (MT) Essentials
Your current capability set only includesABS_MT_POSITION_X, but touch devices require a full set of MT events (like position Y, tracking ID, and pressure) to be recognized correctly by the system.Incorrect Key Events
You've includedKEY_AandKEY_B, which are irrelevant for touch input. Instead, touch devices needBTN_TOUCH(to signal a press) andBTN_TOOL_FINGER(to indicate a single-finger touch).Malformed AbsInfo for MT X Position
The tuple format(0, 255, 128, 0)forABS_MT_POSITION_Xdoesn't match the expectedAbsInfostructure (value, min, max, fuzz, flat, resolution). Always use the explicitAbsInfoobject for consistency.
Corrected Code with Full Touch Emulation
Here's a complete working example that creates a valid touch device and simulates a press, drag, and release:
from evdev import UInput, AbsInfo, ecodes as e import time # Define a valid touch device capability set capabilities = { e.EV_KEY: [e.BTN_TOUCH, e.BTN_TOOL_FINGER], e.EV_ABS: [ # Base X/Y axes (required by some systems) (e.ABS_X, AbsInfo(value=0, min=0, max=255, fuzz=0, flat=0, resolution=0)), (e.ABS_Y, AbsInfo(0, 0, 255, 0, 0, 0)), # Multi-touch mandatory events (e.ABS_MT_TRACKING_ID, AbsInfo(0, 0, 65535, 0, 0, 0)), # Tracks individual touch points (e.ABS_MT_POSITION_X, AbsInfo(0, 0, 255, 0, 0, 0)), (e.ABS_MT_POSITION_Y, AbsInfo(0, 0, 255, 0, 0, 0)), (e.ABS_MT_PRESSURE, AbsInfo(0, 0, 255, 0, 0, 0)) # Optional but recommended for realism ] } try: # Create the virtual touch device ui = UInput(capabilities, name='custom-touch-emulator', version=0x1) print("Virtual touch device created successfully!") # Simulate touch press ui.write(e.EV_KEY, e.BTN_TOUCH, 1) ui.write(e.EV_KEY, e.BTN_TOOL_FINGER, 1) ui.write(e.EV_ABS, e.ABS_MT_TRACKING_ID, 0) # Assign ID 0 to this touch point ui.write(e.EV_ABS, e.ABS_MT_POSITION_X, 50) ui.write(e.EV_ABS, e.ABS_MT_POSITION_Y, 50) ui.write(e.EV_ABS, e.ABS_X, 50) ui.write(e.EV_ABS, e.ABS_Y, 50) ui.write(e.EV_ABS, e.ABS_MT_PRESSURE, 200) ui.syn() # Sync events to trigger system recognition time.sleep(0.5) # Simulate touch drag for pos in range(50, 201, 10): ui.write(e.EV_ABS, e.ABS_MT_POSITION_X, pos) ui.write(e.EV_ABS, e.ABS_MT_POSITION_Y, pos) ui.write(e.EV_ABS, e.ABS_X, pos) ui.write(e.EV_ABS, e.ABS_Y, pos) ui.syn() time.sleep(0.1) # Simulate touch release ui.write(e.EV_KEY, e.BTN_TOUCH, 0) ui.write(e.EV_KEY, e.BTN_TOOL_FINGER, 0) ui.write(e.EV_ABS, e.ABS_MT_TRACKING_ID, -1) # Mark touch point as ended ui.write(e.EV_ABS, e.ABS_MT_PRESSURE, 0) ui.syn() time.sleep(0.5) finally: # Clean up the device ui.close() print("Virtual touch device closed.")
Additional Troubleshooting Tips
- Verify Input Group Membership: Even after adding yourself to the
inputgroup, log out and back in (or restart) to apply the permissions. Check withgroupsin the terminal to confirm. - Load UINPUT Kernel Module: If you still get permission errors, ensure the
uinputmodule is loaded withsudo modprobe uinput. To load it on boot, adduinputto/etc/modules-load.d/uinput.conf. - Update Evdev: Make sure you're using the latest version of the library with
pip install --upgrade evdev.
内容的提问来源于stack exchange,提问作者ovg

