PyQt5: Как подключиться сразу к двум сервисам D-Bus? - PullRequest
0 голосов
/ 05 октября 2018

Я пытаюсь подключиться к двум отдельным службам 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, вы должны поместить свое имя пользователя вместо root в файле .conf.

1 Ответ

0 голосов
/ 05 октября 2018

Оказывается, мне нужно было указать другой путь ('/' выше) для разных интерфейсов.Установка одного на /control и одного на /video устранила проблему.

Я собираюсь стать плотником.Дерево меньше жалуется и лучше горит.

...