Far*_*had 6 qt dbus properties
我正在尝试使用NetworkManager DBus接口获取Qt中所有接口的网络信息(IP地址,网络掩码,路由等).问题是当我尝试访问org.freedesktop.NetworkManager.IP4Config的属性"Addresses"时出现以下错误
QDBusAbstractInterface: type QDBusRawType<0x616175>* must be registered with QtDBus before it can be used to read property org.freedesktop.NetworkManager.IP4Config.Addresses
Addresses are invalid
Error 2 = "Unregistered type QDBusRawType<0x616175>* cannot be handled"
Run Code Online (Sandbox Code Playgroud)
但是我可以使用dbus-send和以下命令获取此属性的值.
dbus-send --system --print-reply --dest=org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager/IP4Config/0 \
org.freedesktop.DBus.Properties.Get \
string:"org.freedesktop.NetworkManager.IP4Config" \
string:"Addresses"
Run Code Online (Sandbox Code Playgroud)
我也可以通过qtdbusviewer获得上述接口提到的属性的良好值.以下是我的代码段.
QDBusInterface interface(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_IFACE, QDBusConnection::systemBus());
// Get a list of all devices
QDBusReply<QList<QDBusObjectPath> > result = interface.call("GetDevices");
foreach (const QDBusObjectPath& connection, result.value()) {
QDBusInterface device(NM_DBUS_SERVICE, connection.path(), "org.freedesktop.NetworkManager.Device", QDBusConnection::systemBus());
if ( device.property("DeviceType").toInt() == NM_DEVICE_TYPE_ETHERNET ) {
// Get the IPv4 information if the device is active
if ( device.property("State").toInt() == NETWORK_DEVICE_CONNECTED ) {
QVariant ipv4config = device.property("Ip4Config");
if ( ipv4config.isValid() ) {
QDBusObjectPath path = qvariant_cast<QDBusObjectPath>(ipv4config);
QDBusInterface ifc(NM_DBUS_SERVICE, path.path(), "org.freedesktop.NetworkManager.IP4Config", QDBusConnection::systemBus());
if ( ifc.isValid() ) {
qDebug() << "Error 1 = " << ifc.lastError().message(); // No error. Everything is OK.
QVariant addresses = ifc.property("Addresses"); // Throwing the QDBusAbstractInterface Error where the property is good and does exist.
if ( addresses.isValid() ) {
qDebug () << "Addresses are valid";
} else {
qDebug () << "Addresses are invalid";
}
qDebug() << "Error 2 = " << ifc.lastError().message();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新#1
我认为它似乎是类型的问题.Qt-Dbus类型系统不理解"地址"属性的类型,因此无法从中创建QVariant.所以我在阅读属性"地址"之前添加了以下行.NetworkManager将属性Addresses定义为以下类型,所以我猜我的typedef很好.
aau - "IPv4地址/前缀/网关的元组数组.每个元组的所有3个元素都按网络字节顺序排列.基本上:[(addr,prefix,gateway),(addr,prefix,gateway),...]"
typedef QList<QList<uint> > Addresses;
Q_DECLARE_METATYPE(Addresses)
qDBusRegisterMetaType<Addresses>()
QVariant addresses = ifc.property("Addresses");
Run Code Online (Sandbox Code Playgroud)
此外,我切换到Qt 5.1(之前我使用的是4.8),我在下面的表单中得到了同样的错误.
Cannot construct placeholder type QDBusRawType
Run Code Online (Sandbox Code Playgroud)
思考/建议
此致,Farrukh Arshad.
就我的研究而言,问题与类型转换有关.属性值采用aau的形式(根据NM Dbus文档).QDbusInterface.property返回QVariant.它确实找到了属性,但无法确定属性的类型,因此给出了错误消息.但我担心的是,我已经在Qt元对象系统中注册了这个属性的自定义类型,就像我在Update#1中提到的那样,为什么它给我这个错误我的类型已经在系统中正确注册并且qDBusRegisterMetaType确实返回了我一个有效的整数.在Qt 5.1中,错误的起源在qdbusmaster.cpp中.一篇文章建议如下所述注册meta类型,但无济于事.
qRegisterMetaType<Addresses>("Addresses");
qDBusRegisterMetaType<Addresses>();
Run Code Online (Sandbox Code Playgroud)
现在我没有时间进一步深入研究是否是某些错误或者我遗漏了什么,但是一旦我有了实际的解决方案,我会更新这篇文章.
替代方法
以下解决方法将用于读取给定的属性值.要使此解决方法起作用,您需要添加qdbus-private而不是qdbus和include.
QVariant ipv4config = device.property("Ip4Config");
if ( ipv4config.isValid() ) {
QDBusObjectPath path = qvariant_cast<QDBusObjectPath>(ipv4config);
QDBusMessage message = QDBusMessage::createMethodCall(NM_DBUS_SERVICE, path.path(), QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get"));
QList<QVariant> arguments;
arguments << "org.freedesktop.NetworkManager.IP4Config" << "Addresses";
message.setArguments(arguments);
QDBusConnection connection = QDBusConnection::systemBus();
QDBusMessage reply = connection.call(message);
foreach(QVariant var, reply.arguments()) {
qDebug () << "String = " << QDBusUtil::argumentToString(var).toHtmlEscaped();
}
}
Run Code Online (Sandbox Code Playgroud)
该字符串将显示您必须从输出中提取的IP地址/子网掩码/路由器IP.为了记录,我从qdbusviewer采取了这种方法.
这不是正确的解决方案,但它会让你暂时摆脱困境.还有一篇很好的文章建议使用Qt Dbus的自定义类型. http://techbase.kde.org/Development/Tutorials/D-Bus/CustomTypes