我有一个 GUI 应用程序(使用 PyQt5 和 QML 制作)并且想在 USB 设备从计算机上插入或拔出时得到通知。经过一番调查,我发现 pyudev 可能是要使用的库。但我无法将它与 PyQt5 和 QML 一起使用。我已成功将pyudev 示例用于 MonitorObservor,文档中还提供了其他示例,此处为 PySide和这里是 Glib。我还在这里找到了一个使用 PyQt5 和小部件应用程序的示例。但我无法在我的 PyQt5 QML 应用程序上实现这一点。我相信这很容易,所以我想我只是错过了一些东西,但我不知道是什么......
这是我到目前为止所拥有的:
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QUrl
from pyudev import Context, Monitor, Device
from pyudev.pyqt5 import MonitorObserver
from Passerelle import *
# def device_connected(self, device):
def device_connected(self):
print("Test")
print("device action: ", device.action, ", path: ", device.device_path)
if __name__ == "__main__":
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
p = Passerelle()
engine.rootContext().setContextProperty("passerelle", p)
engine.load(QUrl("main.qml"))
if not engine.rootObjects:
sys.exit(-1)
context = Context()
monitor = Monitor.from_netlink(context)
# monitor.filter_by(subsystem='tty')
observer = MonitorObserver(monitor)
observer.deviceEvent.connect(device_connected)
monitor.start()
ret = app.exec_()
sys.exit(ret)
拔出或重新插入设备时,我已成功在控制台上打印“测试”,但似乎无法打印设备信息(TypeError: device_connected() missing 1 required positional argument: 'device'
当我取消注释时def device_connected(self, device):
)。
第一步是能够在控制台上打印设备信息,然后找到通知 GUI 的方法,最后仅在插入或拔出的设备具有指定的 VID/PID 时才通知 GUI。
编辑:我找到了一种通过 VID PID 识别设备的方法,使用vid = device.get('ID_VENDOR_ID')
和pid = device.get('ID_MODEL_ID')
对于第二步,我曾想过使用 Passerelle 类作为 QML 后端:
from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal#, pyqtProperty, QUrl
from pyudev import Context, Monitor
from pyudev.pyqt5 import MonitorObserver
def device_event(observer, device):
print ("event ", device.action, " on device ", device)
class Passerelle(QObject):
sendDeviceEvent = pyqtSignal(int)
def __init__(self, parent=None):
print("Passerelle constructor called")
QObject.__init__(self, parent)
print("end Passerelle constructor")
@pyqtSlot()
def setObserverForDeviceEvents(self):
print("setObserverForDeviceEvents called")
context = Context()
monitor = Monitor.from_netlink(context)
monitor.filter_by(subsystem='usb')
observer = MonitorObserver(monitor)
observer.deviceEvent.connect(self.device_connected)
monitor.start()
print("end setObserverForDeviceEvents")
def device_connected(self, device):
print("Test")
print("device action: ", device.action, ", path: ", device.device_path)
但我不确定这是一个好主意,因为我读到文章中读到需要在进入 qt 的主循环之前启动监视器。我的理解是:监视器应该在调用 app.exec_() 之前在 main.py 中启动...
预先感谢您的帮助 !