我想使用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。)
发布于 2012-08-13 23:48:33
好的,诀窍似乎是从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方法的一个很好的例子。
https://stackoverflow.com/questions/11927811
复制相似问题