将 Avahi ServiceBrowser 与 (PyQt5) QtDbus 和连接的插槽一起使用不被调用

Using Avahi ServiceBrowser with (PyQt5) QtDbus and connected slots are not called

我在 PyQt5 中使用 QtDbus 时遇到问题。我想做的是发现某个 Avahi-/Zeroconf 服务类型“_mumble._tcp”。当我启动我的脚本时,当我 start/stop 服务时,我可以看到 dbus-monitor --system 中发出的信号:

signal sender=:1.138 -> dest=:1.273 serial=1413 path=/Client37/ServiceBrowser1; interface=org.freedesktop.Avahi.ServiceBrowser; member=ItemNew
   int32 5
   int32 0
   string "hetzner"
   string "_mumble._tcp"
   string "local"
   uint32 4

这是我的示例代码。如果我观察广播的其他信号,它确实有效,但它不适用于使用创建的 ServiceBrowser 通过 Avahi 发现服务,即它不会在 ServiceBrowser 发出的 "ItemNew" 上触发。

#!/usr/bin/python3

import sys

from PyQt5.QtCore import QObject, QVariant, pyqtSlot
from PyQt5.QtWidgets import QApplication
from PyQt5.QtDBus import QDBusConnection, QDBusInterface


class ServiceDiscoverer(QObject):

    def __init__(self):
        super(ServiceDiscoverer, self).__init__()
        bus = QDBusConnection.systemBus()
        server = QDBusInterface(
            'org.freedesktop.Avahi',
            '/',
            'org.freedesktop.Avahi.Server',
            bus
        )
        flags = QVariant(0)
        flags.convert(QVariant.UInt)
        browser_path = server.call(
            'ServiceBrowserNew',
            -1,  # Interface
            -1,  # Protocol -1 = both, 0 = ipv4, 1 = ipv6
            '_mumble._tcp',
            '', # Domain, default to .local
            flags
        )
        bus.connect(
            'org.freedesktop.Avahi',
            browser_path.arguments()[0],
            'org.freedesktop.Avahi.ServiceBrowser',
            'ItemNew',
            self.onServerAdd
        )

    @pyqtSlot(int, int, str, str, str, int)
    def onServerAdd(self, interface, protocol, key, _type, domain, flags):
        print("Avahi peer added:")
        print(" + Interface: %s" % interface)
        print(" + Protocol: %s" % protocol)
        print(" + Key: %s" % key)
        print(" + Type: %s" % _type)
        print(" + Domain: %s" % domain)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    discoverer = ServiceDiscoverer()
    sys.exit(app.exec_())

我猜我调用的方式有问题bus.connect()。有人对如何捕获信号有建议吗?

Qt 没有正确找到您的插槽。您需要重新装饰您的插槽——您(通过 DBUS)收到的不是带有 6 个参数的函数调用,而是单个 QDBusMessage。试试这个:

...
    @pyqtSlot(QDBusMessage)
    def onServerAdd (self, msg):
        print("Avahi peer added:")
        print(" + Interface: %s" % msg.arguments()[0])
        print(" + Protocol: %s" % msg.arguments()[1])
        print(" + Key: %s" % msg.arguments()[2])
        print(" + Type: %s" % msg.arguments()[3])
        print(" + Domain: %s" % msg.arguments()[4])
...