Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt & DBus problem with slot/method not working
Forum Updated to NodeBB v4.3 + New Features

Qt & DBus problem with slot/method not working

Scheduled Pinned Locked Moved General and Desktop
8 Posts 2 Posters 8.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Doc X
    wrote on last edited by
    #1

    I've been making myself a small DBus testing program for Qt, and have run into a problem, where after scouring the web for a few hours I'm still stumped.

    My object has a public property and public slot. When I run my program, also while using 'qdbusviewer', I see the property and the slot/method, but as soon as I try to call the method (with the qdbusviewer dialog) it says method not found. The test is quite short, so I'll post the whole thing.

    main.cpp
    @#include <iostream>

    #include <QCoreApplication>

    #include "dbusobject.h"

    int main( int argc, char **argv )
    {
    std::cout << "Welcome to DBusObject test" << std::endl;

    QCoreApplication app(argc,argv);
    
    DBusObject obj;
    
    return app.exec();
    

    }

    @

    dbusobject.h
    @#ifndef DBUSOBJECT_H
    #define DBUSOBJECT_H

    #include <QObject>

    class DBusObject : public QObject
    {
    Q_OBJECT
    Q_CLASSINFO("D-Bus Interface", "com.foo.bar.DBusObject")
    Q_PROPERTY(uint globs READ globs)

    public:
    DBusObject(QObject* parent=0);

    uint globs() const;
    

    public slots:
    void setGlobs(const uint);

    private:
    int numGlobs;
    };

    #endif
    @

    dbusobject.cpp
    @
    #include <iostream>

    #include <QDBusConnection>

    #include "dbusobject.h"
    #include "dbusobjectadaptor.h"

    DBusObject::DBusObject(QObject* parent) :
    QObject(parent)
    {
    numGlobs = 0;

    new DBusObjectAdaptor(this);
    
    QDBusConnection connection = QDBusConnection::sessionBus();
    connection.registerObject("/DBusObject", this);
    connection.registerService("com.foo.bar.DBusObject");
    

    }

    uint DBusObject::globs() const
    {
    std::cout << " # of globs=" << numGlobs << std::endl;
    return numGlobs;
    }

    void DBusObject::setGlobs(const uint g)
    {
    std::cout << " setting globs=" << g << std::endl;
    numGlobs = g;
    }

    @

    Using the following commands, I make the adaptor.

    qdbuscpp2xml -M -P dbusobject.h -o com.foo.bar.DBusObject.xml
    qdbusxml2cpp -c DBusObjectAdaptor -a dbusobjectadaptor.h:dbusobjectadaptor.cpp com.foo.bar.DBusObject.xml

    com.foo.bar.DBusObject.xml
    @<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
    <node>
    <interface name="com.foo.bar.DBusObject">
    <property name="globs" type="u" access="read"/>
    <method name="setGlobs">
    <arg type="u" direction="in"/>
    </method>
    </interface>
    </node>
    @

    dbusobjectadaptor.h
    @/*

    • This file was generated by qdbusxml2cpp version 0.7
    • Command line was: qdbusxml2cpp -c DBusObjectAdaptor -a dbusobjectadaptor.h:dbusobjectadaptor.cpp com.foo.bar.DBusObject.xml
    • qdbusxml2cpp is Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
    • This is an auto-generated file.
    • This file may have been hand-edited. Look for HAND-EDIT comments
    • before re-generating it.
      */

    #ifndef DBUSOBJECTADAPTOR_H_1345661941
    #define DBUSOBJECTADAPTOR_H_1345661941

    #include <QtCore/QObject>
    #include <QtDBus/QtDBus>
    class QByteArray;
    template<class T> class QList;
    template<class Key, class Value> class QMap;
    class QString;
    class QStringList;
    class QVariant;

    /*

    • Adaptor class for interface com.foo.bar.DBusObject
      */
      class DBusObjectAdaptor: public QDBusAbstractAdaptor
      {
      Q_OBJECT
      Q_CLASSINFO("D-Bus Interface", "com.foo.bar.DBusObject")
      Q_CLASSINFO("D-Bus Introspection", ""
      " <interface name="com.foo.bar.DBusObject">\n"
      " <property access="read" type="u" name="globs"/>\n"
      " <method name="setGlobs">\n"
      " <arg direction="in" type="u"/>\n"
      " </method>\n"
      " </interface>\n"
      "")
      public:
      DBusObjectAdaptor(QObject *parent);
      virtual ~DBusObjectAdaptor();

    public: // PROPERTIES
    Q_PROPERTY(uint globs READ globs)
    uint globs() const;

    public Q_SLOTS: // METHODS
    void setGlobs(uint in0);
    Q_SIGNALS: // SIGNALS
    };

    #endif
    @

    dbusobjectadaptor.cpp
    @/*

    • This file was generated by qdbusxml2cpp version 0.7
    • Command line was: qdbusxml2cpp -c DBusObjectAdaptor -a dbusobjectadaptor.h:dbusobjectadaptor.cpp com.foo.bar.DBusObject.xml
    • qdbusxml2cpp is Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
    • This is an auto-generated file.
    • Do not edit! All changes made to it will be lost.
      */

    #include "dbusobjectadaptor.h"
    #include <QtCore/QMetaObject>
    #include <QtCore/QByteArray>
    #include <QtCore/QList>
    #include <QtCore/QMap>
    #include <QtCore/QString>
    #include <QtCore/QStringList>
    #include <QtCore/QVariant>

    /*

    • Implementation of adaptor class DBusObjectAdaptor
      */

    DBusObjectAdaptor::DBusObjectAdaptor(QObject *parent)
    : QDBusAbstractAdaptor(parent)
    {
    // constructor
    setAutoRelaySignals(true);
    }

    DBusObjectAdaptor::~DBusObjectAdaptor()
    {
    // destructor
    }

    uint DBusObjectAdaptor::globs() const
    {
    // get the value of property globs
    return qvariant_cast< uint >(parent()->property("globs"));
    }

    void DBusObjectAdaptor::setGlobs(uint in0)
    {
    // handle method call com.foo.bar.DBusObject.setGlobs
    QMetaObject::invokeMethod(parent(), "setGlobs", Q_ARG(uint, in0));
    }

    @

    The entire thing compiles and runs fine, and I can access the property and get a result. When I try to call the setGlobs method I get:

    Unable to find method setGlobs on path /DBusObject in interface com.foo.bar.DBusObject

    What am I missing here?

    1 Reply Last reply
    0
    • D Offline
      D Offline
      Doc X
      wrote on last edited by
      #2

      A quick addendum:

      If I reload 'qdbusviewer' while qbustest is running, I can invoke the method without the error shown above, but nothing ever happens. The adaptor method 'void DBusObjectAdaptor::setGlobs(uint in0)' doesn't get called, nor the slot in my object.

      1 Reply Last reply
      0
      • G Offline
        G Offline
        guziemic
        wrote on last edited by
        #3

        Well, maybe slot is called, but invokeMethod does not work. At least I already experience such kind of problems. You can check if your adapter receives call of slot with some debug like
        @
        #include <QDebug>

        void DBusObjectAdaptor::setGlobs(uint in0)
        {
        // handle method call com.foo.bar.DBusObject.setGlobs

        qDebug() << "Hello I am in adaptor";
        
        QMetaObject::invokeMethod(parent(), "setGlobs", Q_ARG(uint, in0));
        

        }
        @

        On the other hand you can change invoke to direct call of slot
        @
        static_cast<DBusObject *>(paretent())->setGlobs(in0));
        @

        Let me know if that solved your problem.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          Doc X
          wrote on last edited by
          #4

          @void DBusObjectAdaptor::setGlobs(uint in0)@

          does not get called when I use the dialog in 'qdbusviewer'.

          So I assume trying to change the internals of it wont work

          1 Reply Last reply
          0
          • D Offline
            D Offline
            Doc X
            wrote on last edited by
            #5

            qdbusviewer shows property and method:

            !https://lh6.googleusercontent.com/-gYwrlxGw8PY/UDVJcyKhxcI/AAAAAAAAADw/rNJ7wkYeSwQ/s538/qdbus1.png(qdbusviewer)!

            Invoking method, with the unsigned in 123.

            !https://lh6.googleusercontent.com/-j0duxRX92_c/UDVJd6GAeII/AAAAAAAAAD4/ZXSryD2wWcY/s413/qdbus2.png(Using method dialog)!

            Clicking OK does nothing.

            1 Reply Last reply
            0
            • G Offline
              G Offline
              guziemic
              wrote on last edited by
              #6

              You could give a try to my proposition of adding debug, cout or any other text message in adaptor. The method can be called correctly but call of method with realize this interface could fails.

              1 Reply Last reply
              0
              • G Offline
                G Offline
                guziemic
                wrote on last edited by
                #7

                In addition, you could also try another DBus tools to check calling of method, for instance

                d-feet

                dbus-monitor

                Maybe they will give you more information about problem.

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  Doc X
                  wrote on last edited by
                  #8

                  I used dbus-monitor (new to dbus, wasnt aware of its existence) And found the problem.

                  dbus-monitor

                  method call sender=:1.256 -> dest=com.foo.bar.DBusObject serial=31 path=/DBusObject; interface=com.foo.bar.DBusObject; member=setGlobs
                  int32 123
                  error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=31
                  string "No such method 'setGlobs' in interface 'com.foo.bar.DBusObject' at object path '/DBusObject' (signature 'i')"

                  Even though, as seen in the image above, qdbusviewer shows it is taking a uint argument, it apparently is trying to send that argument as a signed int to the method, which fails.

                  I created my own tester program which uses a uint, and the program works as it should.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved