1

GUI アプリケーション (PyQt5 と QML で作成) があり、USB デバイスがコンピューターに接続または切断されたときに通知を受け取りたいと考えています。いくつかの調査の後、pyudev が使用するライブラリである可能性があることがわかりました。しかし、PyQt5 と QML で使用するのに問題があります。MonitorObservor の pyudev の例を使用することに成功しました。ドキュメントには、ここでは 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)

デバイスのプラグを抜き差しすると、コンソールに "Test" を出力することに成功しましたが、デバイス情報を出力できないようです (TypeError: device_connected() missing 1 required positional argument: 'device'コメントを外したときdef device_connected(self, device):)。

ここでの最初のステップは、デバイス情報をコンソールに出力できるようにすることです。次に、GUI に通知する方法を見つけ、最後に、接続または切断されたデバイスに指定された VID/PID がある場合にのみ GUI に通知します。

vid = device.get('ID_VENDOR_ID')編集: VID PID を使用してデバイスを識別する方法を見つけましたpid = device.get('ID_MODEL_ID')

2 番目のステップでは、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 でモニターを開始する必要があることです...

よろしくお願いいたします。

4

1 に答える 1