我正在尝试处理来自多个 USB 键盘的事件,以便代码知道输入来自哪个键盘。该代码通过设备实例 ID 识别不同的键盘(它们都具有相同的产品和供应商 ID),但不识别用户输入的来源(它只是在它们之间切换)。
这对于 pywinusb 来说是可能的吗?我尝试使用事件处理程序但没有运气。
from time import sleep
from msvcrt import kbhit
import pywinusb.hid as hid
# feel free to test
target_vendor_id = 0xffff
target_product_id = 0x0035
def sample_handler(data):
print("Raw data: {0}".format(data))
def getinput(data, id):
print data
print id
if(id == "8&2754010&0&0000" and data == "09008708"):
print "Success"
else:
print "Failed"
def raw_test():
# example, handle the HidDeviceFilter().get_devices() result grouping items by parent ID
all_hids = hid.HidDeviceFilter(vendor_id = target_vendor_id, product_id = target_product_id).get_devices()
#print all_hids
if all_hids:
while True:
for index, device in enumerate(all_hids):
result = device.instance_id.split('\\')[-1]
try:
device.open()
getinput(raw_input(), result)
finally:
device.close()
if __name__ == '__main__':
# first be kind with local encodings
import sys
if sys.version_info >= (3,):
# as is, don't handle unicodes
unicode = str
raw_input = input
else:
# allow to show encoded strings
import codecs
sys.stdout = codecs.getwriter('mbcs')(sys.stdout)
raw_test()
Run Code Online (Sandbox Code Playgroud)
在您的代码中,有一个循环遍历所有 HID 设备(键盘,在本例中是来自)rene-aguirre/pywinusb HidDevice,并一一打开它们以检查输入:
for index, device in enumerate(all_hids):
result = device.instance_id.split('\\')[-1]
try:
device.open()
getinput(raw_input(), result)
finally:
device.close()
Run Code Online (Sandbox Code Playgroud)
该循环打开每个设备,等待输入 ( raw_input()),然后关闭设备。它对 中的每个设备重复此过程all_hids。
它按顺序一个接一个地访问设备。因此它一次只能监听一台设备。每个设备都会打开,等待单个输入,然后关闭。没有对每个键盘进行连续监控。
使用设备实例 ID 和用户输入调用该getinput函数,但这是在同一循环内完成的,不允许您区分来自不同键盘的输入。
因此,您的问题是:您的代码通过设备实例 ID 识别不同的键盘,但无法实时识别输入来自哪个特定键盘。
from time import sleep
import pywinusb.hid as hid
target_vendor_id = 0xffff
target_product_id = 0x0035
# Handler to process the data
def sample_handler(data, device_instance_id):
print(f"Data from {device_instance_id}: {data}")
# Function to open devices and assign handlers
def raw_test():
all_hids = hid.HidDeviceFilter(vendor_id=target_vendor_id, product_id=target_product_id).get_devices()
if all_hids:
for device in all_hids:
device_instance_id = device.instance_id.split('\\')[-1]
try:
device.open()
# Set the handler for the device
device.set_raw_data_handler(lambda data, id=device_instance_id: sample_handler(data, id))
except IOError as e:
print(f"Could not open the device: {e}")
# Keep the script running
print("Press Ctrl+C to stop")
try:
while True:
sleep(0.1)
except KeyboardInterrupt:
pass
finally:
for device in all_hids:
device.close()
if __name__ == '__main__':
raw_test()
Run Code Online (Sandbox Code Playgroud)
这将打开每个设备并设置一个包含设备实例 ID 的处理程序。当接收到数据时,sample_handler将使用数据和数据来源设备的 ID 来调用。
处理程序保持活动状态并持续侦听专门来自其指定键盘的输入:您的代码可以区分来自不同键盘的输入。
device.set_raw_data_handler(lambda data, id=device_instance_id: sample_handler(data, id))
Run Code Online (Sandbox Code Playgroud)
每个设备保持打开状态,并且其处理程序保持活动状态:持续监视每个键盘的输入。
当输入事件发生时,会触发相应的处理程序。由于每个处理程序都知道device_instance_id其键盘的键盘,因此它可以立即识别并报告输入来自哪个键盘。
def sample_handler(data, device_instance_id):
print(f"Data from {device_instance_id}: {data}")
Run Code Online (Sandbox Code Playgroud)
用于device_instance_id识别输入数据的源键盘。