相信来到桌面组的都已经培训过关于DBus服务的adapter和interface的用法,这里再补充一下不借助这种方式直接获取属性,调用其方法,关联其信号的方法:
准备工作:
后面会用到自定义类型,所以我们提前定义它,并实现其<<,>>操作符函数,最后要在使用之前在Qt的元类型系统和Qt D_Bus类型系统注册.以供DBus通讯体系自动识别并使用.
其实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <QDBusMessage> #include <QDBusArgument>
struct DisplayRect{ qint16 x; qint16 y; quint16 width; quint16 height;
operator QRect() const { return QRect(x, y, width, height); } };
Q_DECLARE_METATYPE(DisplayRect)
QDBusArgument &operator<<(QDBusArgument &argument, const DisplayRect &rect); const QDBusArgument &operator>>(const QDBusArgument &argument, DisplayRect &rect); QDebug operator<<(QDebug deg, const DisplayRect &rect);
QDBusArgument &operator<<(QDBusArgument &argument, const DisplayRect &rect) { argument.beginStructure(); argument << rect.x << rect.y << rect.width << rect.height; argument.endStructure(); return argument; }
const QDBusArgument &operator>>(const QDBusArgument &argument, DisplayRect &rect) { argument.beginStructure(); argument >> rect.x >> rect.y >> rect.width >> rect.height; argument.endStructure(); return argument; }
QDebug operator<<(QDebug deg, const DisplayRect &rect) { qDebug() << "x:" << rect.x << "y:" << rect.y << "width:" << rect.width << "height:" << rect.height;
return deg; }
|
qDBusRegisterMetaType<DisplayRect>();
进行注册
1 关联服务属性信号变化并解析当前值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| QDBusConnection::sessionBus().connect("com.deepin.dde.daemon.Dock", "/com/deepin/dde/daemon/Dock", "org.freedesktop.DBus.Properties", "PropertiesChanged", "sa{sv}as", this, SLOT(handleDBusSignal(QDBusMessage)));
void handleDBusSignal(const QDBusMessage &msg) { QList<QVariant> arguments = msg.arguments(); if (3 != arguments.count()) return; QString interfaceName = msg.arguments().at(0).toString(); if (interfaceName != "com.deepin.dde.daemon.Dock") return; QVariantMap changedProps = qdbus_cast<QVariantMap>(arguments.at(1).value<QDBusArgument>()); QStringList keys = changedProps.keys(); foreach (const QString &prop, keys) { if (prop == "FrontendWindowRect") { QVariant ret = changedProps[prop]; QDBusArgument argu = ret.value<QDBusArgument>(); DisplayRect rect; argu >> rect; qDebug() << rect; } else if (prop == "Position") { qDebug() << "Position" << changedProps[prop].toInt(); break; } } }
|
2 获取DBus服务的属性
2.1 原生类型
1 2 3 4 5 6 7 8 9 10 11 12
| QDBusInterface inter2_1("com.deepin.dde.daemon.Dock", "/com/deepin/dde/daemon/Dock", "com.deepin.dde.daemon.Dock", QDBusConnection::sessionBus(), this); qDebug() << inter2_1.property("Position").toInt();
QDBusInterface inter("com.deepin.dde.daemon.Dock", "/com/deepin/dde/daemon/Dock", "com.deepin.dde.daemon.Dock", QDBusConnection::sessionBus(), this); auto entries = inter.property("Entries").value<QList<QDBusObjectPath>>();
|
2.2 自定义类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| QDBusInterface inter2_2("com.deepin.daemon.Display", "/com/deepin/daemon/Display", "org.freedesktop.DBus.Properties"); QString interafce = "com.deepin.daemon.Display"; QString arg1 = "PrimaryRect"; QDBusMessage msg = inter2_2.call("Get", interafce, arg1);
QVariant var = msg.arguments().first(); QDBusVariant dbvFirst = var.value<QDBusVariant>(); QVariant vFirst = dbvFirst.variant(); QDBusArgument dbusArgs = vFirst.value<QDBusArgument>();
DisplayRect rect; dbusArgs >> rect; qDebug() << rect;
|
3 调用DBus服务的方法
3.1 无返回值
1 2 3 4 5 6
| QDBusInterface inter3_1("com.deepin.dde.Clipboard", "/com/deepin/dde/Clipboard", "com.deepin.dde.Clipboard", QDBusConnection::sessionBus(), this); inter3_1.call("Toggle");
|
3.2 有返回值
1 2 3 4 5 6 7
| QDBusInterface inter3_2("com.deepin.daemon.Network", "/com/deepin/daemon/Network", "com.deepin.daemon.Network", QDBusConnection::sessionBus(), this); QDBusMessage msg3_2 = inter3_2.call("GetProxyIgnoreHosts"); qDebug() << msg3_2.arguments().first().toString();
|
3.3 带参调用
1 2 3 4 5 6
| QDBusInterface inter3_3("com.deepin.deepinid.Client", "/com/deepin/deepinid/Client", "com.deepin.deepinid.Client", QDBusConnection::sessionBus(), this); inter3_3.call("Authorize", QString("clientID"), QStringList("list"), QString("callback"), QString("state"));
|
4 通过qdbus命令行查看属性值
// 获取Display服务的PrimartRect属性内容
qdbus --literal com.deepin.daemon.Display /com/deepin/daemon/Display com.deepin.daemon.Display.PrimaryRect
// 获取dock的geometry属性内容
qdbus --literal com.deepin.dde.Dock /com/deepin/dde/Dock com.deepin.dde.Dock.geometry
5 通过dbus-send命令调用服务的方法
// 调用方法[传参]dbus-send支持的参数类型包括:string | int16 | uint16 | int32 | uint32 | int64 | uint64 | double | byte | boolean | objpath
dbus-send --session --print-reply --dest=com.deepin.daemon.Network /com/deepin/daemon/Network com.deepin.daemon.Network.DisconnectDevice string:/org/freedesktop/NetworkManager/Devices/2
6 通过dbus-monitor监听DBus信息流
// 监听服务情况,可得知消息触发源,但监听不到属性被调用
dbus-monitor --session interface=org.freedesktop.Notifications
// 监听信号变化
dbus-monitor --session "type='signal',interface='org.freedesktop.DBus.Properties',path='/com/deepin/dde/daemon/Dock'"
7 通过busctl读写属性
// 查询显示驱动相关信息
busctl get-property com.deepin.system.SystemInfo /com/deepin/system/SystemInfo com.deepin.system.SystemInfo DisplayDriver
// 关闭窗管特效
busctl set-property com.deepin.wm /com/deepin/wm com.deepin.wm compositingEnabled b false