2012-08-13 25 views
0

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

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的工作吗? (我使用了Qt 4.8.1 PyQt4.9.1。)

回答

0

好了,把戏似乎是构建从QDBusPendingCallWatcher实例QDBusPendingReply(非常感谢菲尔·汤普森指出这一点上PyQt mailing list)。事实证明,这种技术也适用于C++。我有移动U盘对象路径错在我的原代码,再加上其他一些小的拼写错误,所以这里是为后人完整,工作示例:

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方法。