如何使用 QDBusAbstractAdaptor 和 PyQt4 在 DBus 上公开方法和属性?

2024-01-09

我正在尝试使用 PyQt4(特别是 QtDBus)在 DBus 上运行一些基本代码。我正在使用 PyQt4 的 Python3 版本。我已经获得了想要在 Qt (c++) 上运行的代码,但我想仅使用 Python 来运行类似的代码。我想在 DBus 上公开方法、信号/槽和属性,以供其他 Python 代码调用。

在 Qt 中,您使用 Q_CLASSINFO 宏/函数来进行 DBus 自省。虽然我已经引入了 Q_CLASSINFO 方法,但我无法让它产生相同类型的功能。据我所知,关于 Q_CLASSINFO 方法的文档为零,所以我不确定是否还有其他方法。使用 D-Feet,我可以清楚地看到没有自动公开任何方法,所以我有点卡住了。

这是我到目前为止所拥有的。

from PyQt4 import QtDBus
from PyQt4.QtCore import QCoreApplication, QObject, Q_CLASSINFO, pyqtSlot, pyqtProperty
from PyQt4.QtDBus import QDBusConnection, QDBusAbstractAdaptor

SERVICE = 'com.home.dbus'

class MyServer(QObject):


    def __init__(self):
        QObject.__init__(self)
        self.__dbusAdaptor = ServerAdaptor(self)

    def close(self):
        pass

    def echo(self, value):
        echoed = 'Received {0}'.format(value)
        return echoed

    def name(self):
        return 'myname'

    def dbus_adaptor(self):
        return self.__dbusAdaptor

class ServerAdaptor(QDBusAbstractAdaptor):
    """ This provides the DBus adaptor to the outside world"""

    def __init__(self, parent):
        super().__init__(parent)
        self.__parent = parent
        Q_CLASSINFO("D-Bus Introspection",
        "  <interface name=\"com.home.dbus\">\n"
        "    <method name=\"name\">\n"
        "      <arg direction=\"out\" type=\"s\" name=\"name\"/>\n"
        "    </method>\n"
        "    <method name=\"echo\">\n"
        "      <arg direction=\"in\" type=\"s\" name=\"phrase\"/>\n"
        "      <arg directory=\"out\" type=\"s\" name=\"echoed\"/>\n"
        "    </method>\n"
        "  </interface>\n")

    def close(self):
        parent.close()

    def echo(self, value):
        return parent.echo(value)

    def name(self):
        return parent.name

def start():
    app = QCoreApplication([])
    if QDBusConnection.sessionBus().isConnected() == False:
        print('Cannot connect to D-Bus session bus')
        return
    print('Starting')
    server = MyServer()
    if not QDBusConnection.sessionBus().registerService(SERVICE):
        print('Unable to register service name')
        return
    if not QDBusConnection.sessionBus().registerObject('/mydbus', server.dbus_adaptor):
        print('Unable to register object at service path')
        return
    app.exec();
    print('Exited')

if __name__ == '__main__':
    start()

虽然我真的很喜欢在 C++ 中使用 QtDBus,因为我想如何构建我的这个大型项目,但我确实需要通过 DBus 访问的对象用 Python3 编写。


您的程序存在几个问题。我建议看看remotecontrolledcar and pingpong来自最新 PyQt 源的示例,它们非常有帮助。主要注意事项是:

  • 你应该通过一个MyServer实例(不是ServerAdaptor) to registerObject()
  • Add pyqtSlot()您希望通过 D-Bus 公开的函数的装饰器
  • Call Q_CLASSINFO()在适配器类的顶部,而不是在其内部__init__()功能
  • 还使用设置“D-Bus Interface”Q_CLASSINFO()
  • 您的内省 XML 包含拼写错误(“目录”而不是“方向”)

这是一个适合我的精简示例(Python 3.2.3/Qt 4.8.2/PyQt 4.9.4):

from PyQt4 import QtDBus
from PyQt4.QtCore import (QCoreApplication, QObject, Q_CLASSINFO, pyqtSlot,
                          pyqtProperty)
from PyQt4.QtDBus import QDBusConnection, QDBusAbstractAdaptor

class MyServer(QObject):

    def __init__(self):
        QObject.__init__(self)
        self.__dbusAdaptor = ServerAdaptor(self)
        self.__name = 'myname'

    def echo(self, value):
        return'Received: {0}'.format(value)

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, value):
        self.__name = value


class ServerAdaptor(QDBusAbstractAdaptor):
    """ This provides the DBus adaptor to the outside world"""

    Q_CLASSINFO("D-Bus Interface", "com.home.dbus")
    Q_CLASSINFO("D-Bus Introspection",
    '  <interface name="com.home.dbus">\n'
    '    <property name="name" type="s" access="readwrite"/>\n'
    '    <method name="echo">\n'
    '      <arg direction="in" type="s" name="phrase"/>\n'
    '      <arg direction="out" type="s" name="echoed"/>\n'
    '    </method>\n'
    '  </interface>\n')

    def __init__(self, parent):
        super().__init__(parent)

    @pyqtSlot(str, result=str)
    def echo(self, phrase):
        return self.parent().echo(phrase)

    @pyqtProperty(str)
    def name(self):
        return self.parent().name

    @name.setter
    def name(self, value):
        self.parent().name = value

def start():
    app = QCoreApplication([])
    bus = QDBusConnection.sessionBus()
    server = MyServer()
    bus.registerObject('/mydbus', server)
    bus.registerService('com.home.dbus')
    app.exec()

if __name__ == '__main__':
    start()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 QDBusAbstractAdaptor 和 PyQt4 在 DBus 上公开方法和属性? 的相关文章

随机推荐

  • 带有缓存存储的 Angular 5

    我尝试在 Angular 5 中使用 CacheStorage 的承诺 如文档中所示 let test caches open test test then result Cache gt result add test png 但我得到了
  • 帮助匹配两个类之间的字段

    我对 Java 还不太有经验 我希望有人能引导我走向正确的方向 因为现在我感觉我只是在用头撞墙 第一个类称为 MeasuredParams 它有 40 多个数字字段 身高 体重 腰围尺寸 手腕尺寸 一些是整数 但大部分是双精度型 第二类是统
  • 保存前受影响的 Mongoose _id

    var mongoose require mongoose mongoose connect mongodb localhost test var Cat mongoose model Cat name String var kitty n
  • Imagebutton 完整图像,圆角

    嗯 我的 Android 应用程序中有一些 ImageButtons 我希望他们展示完整的图片 我的意思是 我希望 ImageButton 只是图片 你知道吗 好吧 到目前为止 一切顺利 我可以使用 背景 属性来做到这一点 不过我也希望 I
  • 部署 Cloud Functions 后出现错误:无法刷新访问令牌。

    我已经用 Firebase Cloud Functions 进行了一段时间的实验 今天我对我的 index json 文件做了一个小小的更改 在要设置的文档中添加了一个字段 在 Firebase Console gt Functions g
  • 如何保持控件禁用直到线程结束

    我正在通过 GPS 调制解调器使用以下代码通过 comport 发送短信 Thread thread null private void btnsend Click object sender EventArgs e if thread n
  • Android:层次结构查看器不存在

    我在 Mac Sierra 上使用 Android Studio 2 3 打开设备监视器时找不到层次结构查看器 视角列表中没有查看者 有人知道这是为什么吗 无法评论 无代表 更新到最新的构建工具后 层次结构查看器和一堆其他东西已从工具目录中
  • MVC Ajax 更新面板

    我知道 至少我很确定 没有像 asp UpdatePanel 这样的 MVC 控件 谁能给我一些关于如何做到这一点的想法 我有一个集合 我从我的存储库和服务层添加条目 在我的主页中 我想根据此集合中是否有任何内容来显示警报 通常我会有一个
  • 使用 Bash 时哪些字符需要转义?

    Bash 中是否有需要转义的字符的完整列表 是否可以仅通过检查sed 特别是 我正在检查是否 是否需要逃避 我试过 echo h h sed s i g 并且工作得很好 没有逃脱 是不是意味着 不需要逃避吗 这是检查必要性的好方法吗 更一般
  • 在 Emacs + Slime + Clojure + Windows 设置中,无法加载 clojure-auto

    我跟着这个非常有用的指南 http dc clj fogus me index php title Installing Clojure and Slime on Windows设置此开发环境 当运行emacs bat我在 Emacs 中收
  • 我该如何处理<>f__AnonymousType0`2[System.Int32,System.String][]?

    我想访问从方法返回的列表 但我得到了错误 未捕获的类型错误 无法读取未定义的属性 长度 当我调试代码时 我在变量结果中得到了返回值 例如f AnonymousType0 2 System Int32 System String 那么如何处理
  • 如何运行 cURL 一次,循环检查域可用性?请帮助修复代码

    我所做的是域可用性检查 它连接到 API 并从 tmp 输出 可用 和不可用 下面的代码只会检查一次可用性 我想多次检查域的可用性 可能是循环 无需每次都重新启动 cURL 连接 因为这浪费时间 我只是不知道如何连接到 cURL 一次并运行
  • 正则表达式模式数字后跟一个字符

    我正在尝试让正则表达式适合以下场景 但遇到了一些麻烦 下面是场景 我的字符串看起来像这样 The office timing h is from 8h to 18h 从上面的字符串我需要 8h and 18h 到目前为止我已经做到了这一点
  • UIScrollview 与 UIButtons - 如何重新创建跳板?

    我正在尝试在我的应用程序中创建一个类似跳板的界面 我正在尝试使用添加到 UIScrollView 的 UIButtons 我遇到的问题是按钮没有将任何触摸传递给 UIScrollView 如果我尝试轻弹 滑动并碰巧按下按钮 它不会注册 UI
  • Objective-C 中子类是否继承其父类的协议?

    假设我有一个实现协议的父类 interface GameViewController UIViewController
  • 如何在玩笑测试中处理 localStorage?

    我在 Jest 测试中不断收到 localStorage 未定义 的消息 这是有道理的 但我的选择是什么 撞砖墙 很好的解决方案来自 chiedo https stackoverflow com users 2015685 chiedo 不
  • 从 matlab 调用 python

    我正在使用 matlab 2016b 很高兴看到 Matlab 中有一些 python 支持 https uk mathworks com help matlab matlab external call python from matla
  • 什么是 Levity 多态性

    正如问题标题所示 我想知道什么是 Levity 多态性以及它的动机是什么 我知道这一页 https ghc haskell org trac ghc wiki NoSubKinds其中有一些细节 但其中的大部分解释都超出了我的理解范围 Wh
  • Next 13 和 Tailwind 深色模式闪烁

    我希望通过 Next 13 的新 appDir 实现本博客中列出的结果 无闪烁深色主题切换 https conermurphy com blog make flicker free dark theme toggle nextjs tail
  • 如何使用 QDBusAbstractAdaptor 和 PyQt4 在 DBus 上公开方法和属性?

    我正在尝试使用 PyQt4 特别是 QtDBus 在 DBus 上运行一些基本代码 我正在使用 PyQt4 的 Python3 版本 我已经获得了想要在 Qt c 上运行的代码 但我想仅使用 Python 来运行类似的代码 我想在 DBus