将 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])
...
我在 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])
...