#include <stdio.h> #include <QObject> #include <QCoreApplication> #include <QDBusConnection> #include <QDBusConnectionInterface> #include <QDBusServiceWatcher> #include <QDebug> #include "Ping.h" #include "../serviceNameAndProperty.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); if (!QDBusConnection::sessionBus().isConnected()) { fprintf(stderr, "Cannot connect to the D-Bus session bus.\n" "To start it, run:\n" "\teval `dbus-launch --auto-syntax`\n"); return 1; } qDebug()<<"Ping connected to D-bus"; Ping ping; QDBusConnectionInterface *iface = QDBusConnection::sessionBus().interface(); QObject::connect(iface, SIGNAL(serviceRegistered(QString)), &ping, SLOT(connectToService(QString))); QObject::connect(iface, SIGNAL(serviceUnregistered(QString)), &ping, SLOT(disconnect(QString))); QStringList registedServices = iface->registeredServiceNames(); if(registedServices.contains(ping.m_aviableServiceName)) ping.connectToService(ping.m_aviableServiceName); return a.exec(); }
#ifndef PING_H #define PING_H #include <QObject> #include <QDBusAbstractInterface> #include <qdbusinterface.h> class Ping : public QObject { Q_OBJECT public: explicit Ping(QObject *parent = 0); public slots: void connectToService(const QString &name); void disconnect(const QString &name); public: QString m_aviableServiceName; private: QDBusInterface *m_interface; QString m_interfaceName; static const QString _propertyName; }; #endif // PING_H
#include "Ping.h" #include "../serviceNameAndProperty.h" #include <QDBusConnectionInterface> #include <QDebug> const QString Ping::_propertyName(QUIOTING(IMAGE_DATA_SHARED_ID)); Ping::Ping(QObject *parent) : QObject(parent) { m_interface = NULL; m_interfaceName = QString(BUFFER_NAME); m_aviableServiceName = QString(SERVICE_NAME); } void Ping::connectToService(const QString &name) { if(name != m_aviableServiceName) return; qDebug()<<"Connceting"; m_interface = new QDBusInterface(name, "/", m_interfaceName, QDBusConnection::sessionBus(), this); if(!m_interface->isValid()){ qDebug()<<"Invalid interface"<<m_interface->lastError(); delete m_interface; m_interface = NULL; return; } qDebug()<<m_interface->interface(); QVariant var("ku"); var = m_interface->property("imageDataSharedId"); qDebug()<<var; } void Ping::disconnect(const QString &name) { if(name != m_aviableServiceName) return; if(name != m_interface->service()) return; delete m_interface; m_interface = NULL; qDebug()<<"Disconnect"; }
#include <QCoreApplication> #include <QDBusConnection> #include <QDBusError> #include <QDebug> #include "Pong.h" #include "../serviceNameAndProperty.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QObject obj; Pong *pong = new Pong(&obj); if( ! QDBusConnection::sessionBus().registerObject("/", &obj)){ fprintf(stderr, "%s\n", qPrintable("Can't register object")); exit(1); } qDebug()<<"Pong connected to D-bus"; if (!QDBusConnection::sessionBus().registerService(SERVICE_NAME)) { fprintf(stderr, "%s\n", qPrintable(QDBusConnection::sessionBus().lastError().message())); exit(1); } qDebug()<<"Test service start"; return a.exec(); }
#ifndef PONG_H #define PONG_H #include <QDBusAbstractAdaptor> #include <QDBusVariant> #include "../serviceNameAndProperty.h" class Pong : public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", BUFFER_NAME) Q_PROPERTY(QString IMAGE_DATA_SHARED_ID READ imageDataSharedId) public: explicit Pong(QObject *parent = nullptr); QString imageDataSharedId(); private: QString m_imageDataSharedId; }; #endif // PONG_H
#include "Pong.h" Pong::Pong(QObject *parent) : QDBusAbstractAdaptor(parent) { m_imageDataSharedId = "testImageBufferId"; } QString Pong::imageDataSharedId() { return m_imageDataSharedId; }
#ifndef SERVICENAMEANDPROPERTY_H #define SERVICENAMEANDPROPERTY_H #define SERVICE_NAME "ru.sonarh.dbus.pong" #define BUFFER_NAME "buffer" #define IMAGE_DATA_SHARED_ID imageDataSharedId #define QUIOTING(text) #text #endif // SERVICENAMEANDPROPERTY_H
QDBusConnectionInterface *iface = c.interface(); connect(iface, SIGNAL(serviceRegistered(QString)), this, SLOT(serviceRegistered(QString))); connect(iface, SIGNAL(serviceUnregistered(QString)), this, SLOT(serviceUnregistered(QString))); connect(iface, SIGNAL(serviceOwnerChanged(QString,QString,QString)), this, SLOT(serviceOwnerChanged(QString,QString,QString)));
void QDBusViewer::serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner) { QModelIndex hit = findItem(servicesModel, name); if (!hit.isValid() && oldOwner.isEmpty() && !newOwner.isEmpty()) serviceRegistered(name); else if (hit.isValid() && !oldOwner.isEmpty() && newOwner.isEmpty()) servicesModel->removeRows(hit.row(), 1); else if (hit.isValid() && !oldOwner.isEmpty() && !newOwner.isEmpty()) { servicesModel->removeRows(hit.row(), 1); serviceRegistered(name); } }
void Ping::manageConnection(const QString& name, const QString &oldVAlue, const QString &newValue) { if(name != m_aviableServiceName) return; if(newValue.isEmpty()) disconnect(name); else connectToService(name); }
QDBusServiceWatcher watcher; watcher.setConnection(QDBusConnection::sessionBus());; QObject::connect(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),&ping, SLOT(manageConnection(QString,QString,QString)));
Compile, run. Doesn't work ... Hey, trolls, you're trolling too fat! Tell me, how should this be used? No, I understand if I add a line watcher.addWatchedService(ping.m_aviableServiceName);
That everything earns money and we even begin to receive signals of registration and deregistration of the service, but what if I don’t know the exact name, and I only know the mask? QDBusMessage message = QDBusMessage::createMethodCall(sig.mService, sig.mPath, QLatin1String("org.freedesktop.DBus.Properties"), QLatin1String("Get")); QList<QVariant> arguments; arguments << sig.mInterface << sig.mName; message.setArguments(arguments); c.callWithCallback(message, this, SLOT(dumpMessage(QDBusMessage)));
QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface,c); if( !iface.isValid()) qDebug()<<(QDBusError(iface.lastError()).message()); else qDebug()<<iface.property(sig.mName.toLatin1().data());
That problem that stopped us will repeat.In order to facilitate the use of:it is not a recommendation or an association, but a binding agreement. And indeed, if you replace BUFFER_NAME with an unintelligible fdgfsgf.buffer, then everything will work.
Service name Network hostnames Dot-separated ("looks like a hostname") Object path URL path component Slash-separated ("looks like a path") Interface Plugin identifier Dot-separated
Pong pong; if( ! QDBusConnection::sessionBus().registerObject("/", &pong)){
then my program crashes with Segmentation fault;Source: https://habr.com/ru/post/185212/
All Articles