PyQt5:如何一次连接到两个 D-Bus 服务?

Posted

技术标签:

【中文标题】PyQt5:如何一次连接到两个 D-Bus 服务?【英文标题】:PyQt5: How to connect to two D-Bus services at once? 【发布时间】:2019-03-10 10:57:24 【问题描述】:

我正在尝试连接到两个单独的 D-Bus 服务,但我只能连接到一个。第二个连接只是连接到第一个服务,尽管报告(通过 provider2API.service())它已连接到第二个服务。

以下最小复制设置两个 d-bus 服务,然后连接并查询它们。

此复制品在 Debian 7 上测试,运行 Python 3.7,导入 PyQt 5.11.2 驱动 Qt 5.11.1。它应该可以在任何接近满足这些要求的 Linux 系统上运行。

import sys, signal
from PyQt5.QtCore import pyqtSlot, QObject, QCoreApplication
from PyQt5.QtDBus import QDBusConnection, QDBusInterface, QDBusReply

signal.signal(signal.SIGINT, signal.SIG_DFL) #Quit on ctrl-c.


#First, set up two D-Bus providers.

QDBusConnection.systemBus().registerService(
    'com.krontech.chronos.control.mock' )
QDBusConnection.systemBus().registerService(
    'com.krontech.chronos.video.mock' )

class Provider1(QObject):
    @pyqtSlot(result=str)
    def exampleCall(self):
        return 'I am #1.'

class Provider2(QObject):
    @pyqtSlot(result=str)
    def exampleCall(self):
        return 'I am #2.' #ERROR: This is never called.

provider1 = Provider1()
QDBusConnection.systemBus().registerObject('/', provider1, 
    QDBusConnection.ExportAllSlots )

provider2 = Provider2()
QDBusConnection.systemBus().registerObject('/', provider2, 
    QDBusConnection.ExportAllSlots )

provider1API = QDBusInterface('com.krontech.chronos.control.mock', '/', '',
    QDBusConnection.systemBus() )
provider2API = QDBusInterface('com.krontech.chronos.video.mock', '/', '',
    QDBusConnection.systemBus() )



#Second, call both D-Bus providers.
#Only one provider is actually called.

app = QCoreApplication(sys.argv)

result1 = QDBusReply(provider1API.call('exampleCall')).value()
result2 = QDBusReply(provider2API.call('exampleCall')).value()

service1 = provider1API.service()
service2 = provider2API.service()

print(f"Provider1: 'result1' on service1")
print(f"Provider2: 'result2' on service2") #ERROR: Prints 'I am #1.'

sys.exit(app.exec_())

输出:

Provider1: 'I am #1.' on com.krontech.chronos.control.mock
Provider2: 'I am #1.' on com.krontech.chronos.video.mock

输出应为:

Provider1: 'I am #1.' on com.krontech.chronos.control.mock
Provider2: 'I am #2.' on com.krontech.chronos.video.mock

(请注意提供商 2 现在如何声称“我是 #2”。)

谢谢!

注意:要让您的系统连接到 D-Bus,您需要将 https://github.com/krontech/chronos-gui-2/blob/bf7dd5fe82eb5636e97ea02f8f0e5d0075318f6d/util/com.krontech.chronos.conf 放入 /etc/dbus-1/system.d/com.krontech.chronos.conf。如果您不是以 root 身份运行,则应在 .conf 文件中使用自己的用户名代替 root。

【问题讨论】:

【参考方案1】:

原来我需要为不同的接口指定不同的路径(上面的'/')。将一个设置为/control 并将一个设置为/video 可以解决此问题。

我要成为一名木匠。木材抱怨更少,燃烧更好。

【讨论】:

以上是关于PyQt5:如何一次连接到两个 D-Bus 服务?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过多个类一次连接到 MySQL 数据库

systemd 服务无法连接到会话 d-bus

PyQt5 连接到 Websocket - 等待来自服务器的信号

记一次连不上wifi网的处理

CVLC 无法连接到 D-Bus 会话

PyQt5 在 dbus 请求失败时创建错误