首页 > 解决方案 > D-Bus python PyQt5 服务示例

问题描述

我正在尝试建立一个 PyQt5 D-Bus 服务示例。

到目前为止,这是我的代码

#!/usr/bin/python3
from PyQt5.QtCore import QCoreApplication, Q_CLASSINFO, pyqtSlot, QObject
from PyQt5.QtDBus import QDBusConnection, QDBusAbstractAdaptor

import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

class Service(QDBusAbstractAdaptor):
    Q_CLASSINFO('D-Bus Interface', 'org.example.chat')
    Q_CLASSINFO('D-Bus Introspection', ''
                '  <interface name="org.example.chat">\n'
                '    <method name="GetLastInput">\n'
                '      <arg direction="out" type="s" name="text"/>\n'
                '    </method>\n'
                '  </interface>\n'
                '')

    def __init__(self, parent):
        super().__init__(parent)
        QDBusConnection.sessionBus().registerObject("/", self)

        if not QDBusConnection.sessionBus().registerService("org.example.chat"):
            print(QDBusConnection.sessionBus().lastError().message())

    @pyqtSlot()
    def GetLastInput(self):
        return 'hello'


if __name__ == '__main__':
    app = QCoreApplication([])

    if not QDBusConnection.sessionBus().isConnected():
        print ("Cannot connect to the D-Bus session bus.\n"
               "Please check your system settings and try again.\n");

    service = Service(app)
    print ('Now we are running')
    app.exec_()

这运行没有错误,但“org.example.chat”界面未导出

~$ dbus-send --session --dest="org.example.chat" --type="method_call" --print-reply "/" "org.example.chat.GetLastInput"

Error org.freedesktop.DBus.Error.UnknownInterface: No such interface 'org.example.chat' at object path '/'

用 d-feet 浏览 / 对象,我只看到这些接口:

我错过了什么?

谢谢

标签: pythonservicepyqt5dbus

解决方案


要注册的对象不能是适配器本身,而是另一个QObject。

正如文档所解释的:

[...] 这是通过将一个或多个派生自 QDBusAbstractAdaptor 的类附加到一个普通的 QObject,然后使用 registerObject()注册该QObject 来实现的。

将参数更改registerObject为父级,它将起作用:

    def __init__(self, parent):
        super().__init__(parent)
        QDBusConnection.sessionBus().registerObject("/", parent)

您还需要将result参数添加到插槽中,否则它将不起作用:

    @pyqtSlot(result=str)
    def GetLastInput(self):
        return 'hello'

推荐阅读