I am trying to connect to two separate D-Bus services, but I can only connect to one. The second connection just connects to the first service, despite reporting (via provider2API.service()) that it is connected to the second service.
The following minimal reproduction sets up two d-bus services, then connects and queries to both of them.
This reproduction is tested on Debian 7, running Python 3.7, importing PyQt 5.11.2 driving Qt 5.11.1. It should work on any Linux system which comes close to meeting these requirements.
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_())
Output:
Provider1: 'I am #1.' on com.krontech.chronos.control.mock
Provider2: 'I am #1.' on com.krontech.chronos.video.mock
The output should read:
Provider1: 'I am #1.' on com.krontech.chronos.control.mock
Provider2: 'I am #2.' on com.krontech.chronos.video.mock
(Note how provider 2 is now claiming 'I am #2'.)
Thank you!
Note: To allow your system to connect to D-Bus, you will need to put https://github.com/krontech/chronos-gui-2/blob/bf7dd5fe82eb5636e97ea02f8f0e5d0075318f6d/util/com.krontech.chronos.conf in /etc/dbus-1/system.d/com.krontech.chronos.conf
. If you're not running as root, you should put your own user name in place of root in the .conf file.