【问题标题】:Process QDBusPendingCallWatcher results in PyQt4?在 PyQt4 中处理 QDBusPendingCallWatcher 结果?
【发布时间】:2012-08-13 03:20:21
【问题描述】:

我想使用 PyQt4.QtDBus 对远程 D-Bus 服务中的函数进行非阻塞调用。改编自 Qt 的 C++ 文档,我想出了以下测试程序:

from PyQt4 import QtCore, QtDBus

class DeviceInterface(QtDBus.QDBusAbstractInterface):

    def __init__(self, service, path, connection, parent=None):
        super().__init__(service, path, 'org.freedesktop.UDisks.Device',
                         connection, parent)

    @QtCore.pyqtSlot(QtDBus.QDBusArgument)
    def callFinishedSlot(self, arg):
        print("Got result:", arg)


if __name__ == '__main__':
    import sys
    app = QtCore.QCoreApplication(sys.argv)

    dev = DeviceInterface('org.freedesktop.UDisks',
                          '/org/freedesktop/UDisks/devices/sda1',
                          QtDBus.QDBusConnection.systemBus(), app)

    async = dev.asyncCall("FilesystemListOpenFiles");
    watcher = QtDBus.QDBusPendingCallWatcher(async, dev)
    watcher.finished.connect(dev.callFinishedSlot)
    sys.exit(app.exec_())

它似乎工作。当我运行它时,它会打印:

Got result: <PyQt4.QtDBus.QDBusPendingCallWatcher object at 0xb740c77c>

问题是,我不知道如何将QDBusPendingCallWatcher 转换为可以从中提取结果的东西(例如QDBusMessage)。 C++ documentation 中的示例是这样做的:

 void MyClass.callFinishedSlot(QDBusPendingCallWatcher *call)
 {
     QDBusPendingReply<QString, QByteArray> reply = *call;
     if (reply.isError()) {
         showError();
     } else {
         QString text = reply.argumentAt<0>();
         QByteArray data = reply.argumentAt<1>();
         showReply(text, data);
     }
     call->deleteLater();
 }

谁能告诉我如何将 C++ 插槽转换为适用于 PyQt4 的东西? (我将 PyQt4.9.1 与 Qt 4.8.1 一起使用。)

【问题讨论】:

    标签: pyqt4 dbus qtdbus


    【解决方案1】:

    好的,诀窍似乎是从QDBusPendingCallWatcher 实例构造一个QDBusPendingReply(非常感谢Phil Thompson 在PyQt mailing list 上指出这一点)。事实证明,同样的技术也适用于 C++。我的原始代码中的 UDisk 对象路径错误,加上其他一些小错别字,所以这里有一个完整的工作示例,供后人参考:

    from PyQt4 import QtCore, QtDBus
    
    class DeviceInterface(QtDBus.QDBusAbstractInterface):
    
        def __init__(self, service, path, connection, parent=None):
            super().__init__(service, path, 'org.freedesktop.UDisks.Device',
                             connection, parent)
    
        def callFinishedSlot(self, call):
            # Construct a reply object from the QDBusPendingCallWatcher
            reply = QtDBus.QDBusPendingReply(call)
            if reply.isError():
                print(reply.error().message())
            else:
                print("  PID        UID     COMMAND")
                print("-------    -------   ------------------------------------")
                for pid, uid, cmd in reply.argumentAt(0):
                    print("{0:>7d}    {1:>7d}   {2}".format(pid, uid, cmd))
            # Important: Tell Qt we are finished processing this message
            call.deleteLater()
    
    if __name__ == '__main__':
        import sys
        import signal
        signal.signal(signal.SIGINT, signal.SIG_DFL)
    
        app = QtCore.QCoreApplication(sys.argv)
    
        dev = DeviceInterface('org.freedesktop.UDisks',
                              '/org/freedesktop/UDisks/devices/sda1',
                              QtDBus.QDBusConnection.systemBus(), app)
    
        async = dev.asyncCall("FilesystemListOpenFiles");
        watcher = QtDBus.QDBusPendingCallWatcher(async, dev)
        watcher.finished.connect(dev.callFinishedSlot)
        sys.exit(app.exec_())
    

    这应该适用于最新的 Linux 发行版,并且是使用 PyQt 调用返回复合类型的 D-Bus 方法的一个很好的例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-13
      • 2017-10-18
      • 2023-04-05
      • 2012-03-14
      • 1970-01-01
      • 2019-04-11
      • 2013-09-28
      • 2015-06-19
      相关资源
      最近更新 更多