struct Money { int summ; QString type; Money() : summ(0) , type() {} };
<Q_DECLARE_METATYPE(Money)>
<qRegisterMetaType<Money;>("Money");
qDBusRegisterMetaType<Money;>();>
friend QDBusArgument& operator <<(QDBusArgument& argument, const Money& arg) { argument.beginStructure(); argument << arg.summ; argument << arg.type; argument.endStructure(); return argument; } friend const QDBusArgument& operator >>(const QDBusArgument& argument, Money& arg) { argument.beginStructure(); argument >> arg.summ; argument >> arg.type; argument.endStructure(); return argument; }
#include <QString> #include <QDateTime> #include <QMap> #include <QMetaType> #include <QtDBus> // D-Bus namespace dbus { static QString serviceName() { return "org.student.interface"; } static QString servicePath() { return "/org/student/interface"; } } struct Money { int summ; QString type; Money() : summ(0) , type() {} friend QDBusArgument &operator<<(QDBusArgument &argument, const Money &arg); friend const QDBusArgument &operator>>(const QDBusArgument &argument, Money &arg); }; Q_DECLARE_METATYPE(Money) struct Letter { Money summ; QString text; QDateTime letterDate; Letter() : summ() , text() , letterDate() {} friend QDBusArgument &operator<<(QDBusArgument &argument, const Letter &arg); friend const QDBusArgument &operator>>(const QDBusArgument &argument, Letter &arg); }; Q_DECLARE_METATYPE(Letter) // typedef QList<QVariant> Stuff; Q_DECLARE_METATYPE(Stuff) struct Parcel { Stuff someFood; Letter letter; Parcel() : someFood() , letter() {} friend QDBusArgument &operator<<(QDBusArgument &argument, const Parcel &arg); friend const QDBusArgument &operator>>(const QDBusArgument &argument, Parcel &arg); }; Q_DECLARE_METATYPE(Parcel)
#include "types.h" #include <QMetaType> #include <QtDBus> // static struct RegisterTypes { RegisterTypes() { qRegisterMetaType<Money>("Money"); qDBusRegisterMetaType<Money>(); qRegisterMetaType<Letter>("Letter"); qDBusRegisterMetaType<Letter>(); qRegisterMetaType<Stuff>("Stuff"); qDBusRegisterMetaType<Stuff>(); qRegisterMetaType<Parcel>("Parcel"); qDBusRegisterMetaType<Parcel>(); } } RegisterTypes; //------------------------ QDBusArgument& operator <<(QDBusArgument& argument, const Money& arg) { argument.beginStructure(); argument << arg.summ; argument << arg.type; argument.endStructure(); return argument; } const QDBusArgument& operator >>(const QDBusArgument& argument, Money& arg) { argument.beginStructure(); argument >> arg.summ; argument >> arg.type; argument.endStructure(); return argument; } //------------------------ QDBusArgument& operator <<(QDBusArgument& argument, const Letter& arg) { argument.beginStructure(); argument << arg.summ; argument << arg.text; argument << arg.letterDate; argument.endStructure(); return argument; } const QDBusArgument& operator >>(const QDBusArgument& argument, Letter& arg) { argument.beginStructure(); argument >> arg.summ; argument >> arg.text; argument >> arg.letterDate; argument.endStructure(); return argument; } //------------------------ QDBusArgument& operator <<(QDBusArgument& argument, const Parcel& arg) { argument.beginStructure(); argument << arg.someFood; argument << arg.letter; argument.endStructure(); return argument; } const QDBusArgument& operator >>(const QDBusArgument& argument, Parcel& arg) { argument.beginStructure(); argument >> arg.someFood; argument >> arg.letter; argument.endStructure(); return argument; }
#include <QObject> #include "../lib/types.h" class Student : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.student.interface") public: Student(QObject *parent = 0); ~Student(); signals: Q_SCRIPTABLE Q_NOREPLY void needHelp(Letter reason); void parcelRecived(QString parcelDescription); public slots: Q_SCRIPTABLE void reciveParcel(Parcel parcelFromParents); void sendLetterToParents(QString letterText); private: void registerService(); };
void Student::registerService() { QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, dbus::serviceName()); if (!connection.isConnected()) qDebug()<<(QString("DBus connect false")); else qDebug()<<(QString("DBus connect is successfully")); if (!connection.registerObject(dbus::servicePath(), this, QDBusConnection::ExportScriptableContents)) { qDebug()<<(QString("DBus register object false. Error: %1").arg(connection.lastError().message())); } else qDebug()<<(QString("DBus register object successfully")); if (!connection.registerService(dbus::serviceName())) { qDebug()<<(QString("DBus register service false. Error: %1").arg(connection.lastError().message())); } else qDebug()<<(QString("DBus register service successfully")); }
#include "student.h" #include <QDBusConnection> #include <QDebug> #include <QDBusError> Student::Student(QObject *parent) : QObject(parent) { registerService(); } Student::~Student() { } void Student::reciveParcel(Parcel parcelFromParents) { QString letterText = parcelFromParents.letter.text; letterText.append(QString("\n Money: %1 %2").arg(parcelFromParents.letter.summ.summ).arg(parcelFromParents.letter.summ.type)); Stuff sendedStuff = parcelFromParents.someFood; QString stuffText; foreach(QVariant food, sendedStuff) { stuffText.append(QString("Stuff: %1\n").arg(food.toString())); } QString parcelDescription; parcelDescription.append(letterText); parcelDescription.append("\n"); parcelDescription.append(stuffText); emit parcelRecived(parcelDescription); } void Student::sendLetterToParents(QString letterText) { Letter letterToParents; letterToParents.text = letterText; letterToParents.letterDate = QDateTime::currentDateTime(); emit needHelp(letterToParents); } void Student::registerService() { QDBusConnection connection = QDBusConnection::connectToBus(QDBusConnection::SessionBus, dbus::serviceName()); if (!connection.isConnected()) qDebug()<<(QString("DBus connect false")); else qDebug()<<(QString("DBus connect is successfully")); if (!connection.registerObject(dbus::servicePath(), this, QDBusConnection::ExportScriptableContents)) { qDebug()<<(QString("DBus register object false. Error: %1").arg(connection.lastError().message())); } else qDebug()<<(QString("DBus register object successfully")); if (!connection.registerService(dbus::serviceName())) { qDebug()<<(QString("DBus register service false. Error: %1").arg(connection.lastError().message())); } else qDebug()<<(QString("DBus register service successfully")); }
const QString studentMethod = "reciveParcel"; QDBusMessage sendParcel = QDBusMessage::createMethodCall(dbus::serviceName(), dbus::servicePath(), "", studentMethod); QList<QVariant> arg; arg.append(qVariantFromValue(parentsParcel)); sendParcel.setArguments(arg); if ( !QDBusConnection::sessionBus().send(sendParcel) ) { qDebug()<<QString("D-bus %1 calling error: %2").arg(studentMethod).arg(QDBusConnection::sessionBus().lastError().message()); }
const QString studentMethod = "reciveParcel"; QDBusMessage sendParcel = QDBusMessage::createMethodCall(dbus::serviceName(), dbus::servicePath(), "", studentMethod); QList<QVariant> arg; arg.append(qVariantFromValue(parentsParcel)); sendParcel.setArguments(arg); int timeout = 25; // , - 25 QDBusReply<int> reply = QDBusConnection::sessionBus().call(sendParcel, QDBus::Block, timeout); //QDBus::Block (event loop) if (!reply.isValid()) { qDebug()<<QString("D-bus %1 calling error: %2").arg(studentMethod).arg(QDBusConnection::sessionBus().lastError().message()); } int returnedValue = reply.value();
const QString studentMethod = "reciveParcel"; QDBusMessage sendParcel = QDBusMessage::createMethodCall(dbus::serviceName(), dbus::servicePath(), "", studentMethod); QList<QVariant> arg; arg.append(qVariantFromValue(parentsParcel)); sendParcel.setArguments(arg); int timeout = 25; // , - 25 bool isCalled = QDBusConnection::sessionBus().callWithCallback(sendParcel, this, SLOT(standartSlot(int)), SLOT(errorHandlerSlot(const QDBusMessage&)), timeout) if (!isCalled) { qDebug()<<QString("D-bus %1 calling error: %2").arg(studentMethod).arg(QDBusConnection::sessionBus().lastError().message()); }
QDBusMessage msg = QDBusMessage::createSignal(dbus::servicePath(), dbus::serviceName(), "someSignal"); msg << signalArgument; QDBusConnection::sessionBus().send(msg);
#include <QObject> #include "../lib/types.h" class Parents : public QObject { Q_OBJECT public: Parents(QObject *parent = 0); ~Parents(); private slots: void reciveLetter(const Letter letterFromStudent); private: void connectToDBusSignal(); void sendHelpToChild(const Letter letterFromStudent) const; void sendParcel(const Parcel parentsParcel) const; Letter writeLetter(const Letter letterFromStudent) const; Stuff poskrestiPoSusekam() const; };
#include "parents.h" #include <QDBusConnection> #include <QDebug> Parents::Parents(QObject *parent) : QObject(parent) { connectToDBusSignal(); } Parents::~Parents() { } void Parents::reciveLetter(const Letter letterFromStudent) { qDebug()<<"Letter recived: "; qDebug()<<"Letter text: "<<letterFromStudent.text; qDebug()<<"Letter date: "<<letterFromStudent.letterDate; sendHelpToChild(letterFromStudent); } void Parents::connectToDBusSignal() { bool isConnected = QDBusConnection::sessionBus().connect( "", dbus::servicePath(), dbus::serviceName(), "needHelp", this, SLOT(reciveLetter(Letter))); if(!isConnected) qDebug()<<"Can't connect to needHelp signal"; else qDebug()<<"connect to needHelp signal"; } void Parents::sendHelpToChild(const Letter letterFromStudent) const { Parcel preparingParcel; preparingParcel.letter = writeLetter(letterFromStudent); preparingParcel.someFood = poskrestiPoSusekam(); sendParcel(preparingParcel); } void Parents::sendParcel(const Parcel parentsParcel) const { const QString studentMethod = "reciveParcel"; QDBusMessage sendParcel = QDBusMessage::createMethodCall(dbus::serviceName(), dbus::servicePath(), "", studentMethod); QList<QVariant> arg; arg.append(qVariantFromValue(parentsParcel)); sendParcel.setArguments(arg); if ( !QDBusConnection::sessionBus().send( sendParcel) ) { qDebug()<<QString("D-bus %1 calling error: %2").arg(studentMethod).arg(QDBusConnection::sessionBus().lastError().message()); } } Letter Parents::writeLetter(const Letter letterFromStudent) const { QString text = "We read about you problem so send some help"; Letter parentLetter; parentLetter.text = text; Money summ; summ.summ = letterFromStudent.text.count(",")*100; summ.summ += letterFromStudent.text.count(".")*50; summ.summ += letterFromStudent.text.count(" ")*5; summ.type = "USD"; parentLetter.summ = summ; parentLetter.letterDate = QDateTime::currentDateTime(); return parentLetter; } Stuff Parents::poskrestiPoSusekam() const { Stuff food; food<<"Russian donuts"; food<<"Meat dumplings"; return food; }
… class Student : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.student.interface") Q_CLASSINFO("D-Bus Introspection", "" "<interface name=\"org.student.interface\">\n" " <signal name=\"needHelp\">\n" " <arg name=\"reason\" type=\"((is)s((iii)(iiii)i))\" direction=\"out\"/>\n" " <annotation name=\"com.chameleon.QtDBus.QtTypeName.Out0\" value=\"Letter\"/>\n" " </signal>\n" " <method name=\"reciveParcel\">\n" " <arg name=\"parcelFromParents\" type=\"(av((is)s((iii)(iiii)i)))\" direction=\"in\"/>\n" " <annotation name=\"org.qtproject.QtDBus.QtTypeName.In0\" value=\"Parcel\"/>\n" " <annotation name=\"org.freedesktop.DBus.Method.NoReply\" value=\"true\"/>\n" " </method>\n" ) public: Student(QObject *parent = 0); …
QDBusArgument arg; arg<<Parcel(); qDebug()<<"Parcel signature: "<<arg.currentSignature();
Source: https://habr.com/ru/post/220687/