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. QtDBus: how to use enumeration?
Forum Updated to NodeBB v4.3 + New Features

QtDBus: how to use enumeration?

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 1 Posters 352 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.
  • BeatussumB Offline
    BeatussumB Offline
    Beatussum
    wrote on last edited by Beatussum
    #1

    Hello,
    I have tried, for almost two days, to make enumeration work with QtDBus. In the following source files, getColor() and setColor() work but not getMode() and setMode().

    dbus/DBusLedInterface.hpp:

    #include "dbus/DBusIndexableInterface.hpp" // just provides a getIndex() method
    #include "dbus/EnumDBus.hpp"
    
    #include <QDBusMetaType>
    
    
    struct Color
    {
        uint32_t red;
        uint32_t green;
        uint32_t blue;
    };
    Q_DECLARE_METATYPE(Color)
    
    QDBusArgument& operator<<(QDBusArgument& argument, const Color& color);
    const QDBusArgument& operator>>(const QDBusArgument& argument, Color& color);
    
    enum Modes : quint32
    {
        Off = 0,
        Constant = 1,
        ColorSet = 2,
        Breathing = 3
    };
    Q_DECLARE_METATYPE(Modes)
    
    enum ColorDepth : quint32
    {
        ZeroBits = 0,
        EightBits = 1,
        OneBit = 2
    };
    Q_DECLARE_METATYPE(ColorDepth)
    
    class DBusLedInterface final : public DBusIndexableInterface
    {
        Q_OBJECT
    
    public:
        DBusLedInterface(const QString& obj) noexcept
            : DBusIndexableInterface("Led", obj)
        {
            qDBusRegisterMetaType<Color>();
            qDBusRegisterMetaType<Modes>();
        }
    
        Q_PROPERTY(Modes Mode READ getMode WRITE setMode)
        Modes getMode() const;
        void setMode(const Modes mode);
    
        Q_PROPERTY(Color Color READ getColor WRITE setColor)
        Color getColor() const;
        void setColor(const Color color);
    
       //…
    };
    

    DBusLedInterface.cpp:

    #include "dbus/DBusLedInterface.hpp"
    
    
    Modes DBusLedInterface::getMode() const
    {
        return getPropertyAndCheck<Modes>("Mode");
    }
    
    void DBusLedInterface::setMode(const Modes mode)
    {
        setPropertyAndCheck("Mode", mode);
    }
    
    Color DBusLedInterface::getColor() const
    {
         return getPropertyAndCheck<Color>("Color");
    }
    
    void DBusLedInterface::setColor(const Color color)
    {
        setPropertyAndCheck("Color", color);
    }
    
    // …
    
    QDBusArgument& operator<<(QDBusArgument& argument, const Color& color)
    {
        argument.beginStructure();
        argument << color.red << color.green << color.blue;
        argument.endStructure();
    
        return argument;
    }
    
    const QDBusArgument& operator>>(const QDBusArgument& argument, Color& color)
    {
        argument.beginStructure();
        argument >> color.red >> color.green >> color.blue;
        argument.endStructure();
    
        return argument;
    }
    

    dbus/DBusAbstractInterface.hpp:

    #include <QtDBus/QDBusInterface>
    #include <QtDBus/QDBusReply>
    
    
    class DBusPropertyException final : public std::runtime_error
    {
    public:
        DBusPropertyException(const char* name, const std::string& suffix = ".")
            : std::runtime_error("Unable to get or set the property "
                                 + std::string(name) + suffix)
        {}
    
        DBusPropertyException(const char* name, const char* desc)
            : DBusPropertyException(name, ": " + std::string(desc) + '.')
        {}
    };
    
    
    class DBusAbstractInterface : public QDBusInterface
    {
    public:
        // …
    
        template<class T>
        T getPropertyAndCheck(const char* name) const;
    
        template<class T>
        void setPropertyAndCheck(const char* name, T value);
    
        // …
    };
    
    template<class T>
    T DBusAbstractInterface::getPropertyAndCheck(const char* name) const
    {
        QVariant ret = property(name);
    
        if (!ret.isValid()) {
            throw DBusPropertyException(name, "The QVariant is not valid");
        } else {
            return qvariant_cast<T>(ret);
        }
    }
    
    template<class T>
    void DBusAbstractInterface::setPropertyAndCheck(const char* name, T value)
    {
        if (!setProperty(name, QVariant::fromValue(value)))
            throw DBusPropertyException(name);
    }
    

    dbus/EnumDBus.hpp (inspired by https://techbase.kde.org/Development/Tutorials/D-Bus/CustomTypes#enumDBus.hpp/):

    #include <QtDBus/QDBusArgument>
    
    
    template<typename T, bool isEnum>
    class QDBusEnumMarshal;
    
    template<typename T>
    class QDBusEnumMarshal<T, true>
    {
    public:
        using enum_t = typename std::underlying_type<T>::type;
    
        static QDBusArgument& marshal(QDBusArgument& arg, const T& src)
        {
            arg.beginStructure();
            arg << static_cast<enum_t>(src);
            arg.endStructure();
    
            return arg;
        }
    
        static const QDBusArgument& unmarshal(const QDBusArgument& arg, T& src)
        {
            enum_t tmp;
    
            arg.beginStructure();
            arg >> tmp;
            arg.endStructure();
    
            src = static_cast<T>(tmp);
            return arg;
        }
    };
    
    template<typename T>
    QDBusArgument& operator<<(QDBusArgument& arg, const T& src)
    {
        return QDBusEnumMarshal<T, std::is_enum<T>::value>::marshal(arg, src);
    }
    
    template<typename T>
    const QDBusArgument& operator>>(const QDBusArgument& arg, T& src)
    {
        return QDBusEnumMarshal<T, std::is_enum<T>::value>::unmarshal(arg, src);
    }
    
    1 Reply Last reply
    0
    • BeatussumB Offline
      BeatussumB Offline
      Beatussum
      wrote on last edited by
      #2

      I have found a workaround by creating a private Q_PROPERTY of type quint32 (the original type of my Mode property), and I cast then to my custom enumeration type Modes. But, if someone has a better solution, I'm still a taker…

      dbus/DBusLedInterface.hpp:

      #include "dbus/DBusIndexableInterface.hpp" // just provides a `getIndex()` method
      
      // …
      
      class DBusLedInterface : public DBusIndexableInterface
      {
          Q_OBJECT
          Q_PROPERTY(quint32 Mode READ getMode_ WRITE setMode_)
      
      public:
          enum Modes {
              Off = 0,
              Constant = 1,
              Cycles = 2,
              Breathing = 3
          };
      public:
          // …
      
          Modes getMode() const;
          void setMode(const Modes mode);
      
          // …
      private:
          quint32 getMode_() const;
          void setMode_(const quint32 mode);
      };
      

      dbus/DBusLedInterface.cpp:

      #include "dbus/DBusLedInterface.hpp"
      
      // …
      
      DBusLedInterface::Modes DBusLedInterface::getMode() const
      {
           return static_cast<Modes>(getMode_());
      }
      
      void DBusLedInterface::setMode(const Modes mode)
      {
          setMode_(static_cast<quint32>(mode));
      }
      
      quint32 DBusLedInterface::getMode_() const
      {
           return getPropertyAndCheck<quint32>("Mode");
      }
      
      void DBusLedInterface::setMode_(const quint32 mode)
      {
          setPropertyAndCheck("Mode", mode);
      }
      
      // …
      
      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