1

My class has enum property, i wish to access this property using QObject*. When calling QVariant QObject::property ( const char * name ) const return value is empty QVariant of enum type.

Consider the following code:

/* Interface class */
class IFoo
{
Q_GADGET
public:
  Q_ENUMS(ColorType)

  typedef enum
  {
    COLOR_RED = 0,
    COLOR_BLUE
  } ColorType;

  virtual QString Name(void) const = 0;
};
Q_DECLARE_METATYPE(IFoo::ColorType)

class Foo
  : public IFoo
{
Q_OBJECT
public:
  Foo(void) 
  {
    qint32 typeId = qRegisterMetaType<IFoo::ColorType>("ColorType");
    qRegisterMetaTypeStreamOperators<int>(IFoo::ColorType);
  }
  virtual QString Name(void) const { return _name; }

  void SetColor(ColorType color) { _color = color; }
  ColorType Color(void) const { return _color; }
  QString ColorString(void) const { return _color == IFoo::COLOR_RED ? "Red" : "Blue"; }

  Q_PROPERTY(IFoo::ColorType Color READ Color WRITE SetColor)
  Q_PROPERTY(QString ColorString READ ColorString)

private:
  ColorType _color;
  QString _name;
};

int main (int argc, char **argv) {
  QCoreApplication app(argc, argv);

  Foo f;
  f.SetColor(IFoo::COLOR_RED);

  qDebug() << f.property("Color"); // Returns QVariant(IFoo::ColorType, ) 
  qDebug() << f.property("ColorString"); // Returns QString(Red)
}

Why does property return empty QVariant value? String wrapper property works as it should.

BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
krizajb
  • 1,715
  • 3
  • 30
  • 43
  • Is it really empty? Have you tried calling QVariant::value()? Also, have you tried using Q_DECLARE_METATYPE? – Taylor Brandstetter Nov 20 '13 at 15:21
  • Seems u are right .. QVariant::value() returned correct int value. Unfortunately that doesn't help me much, or is it possible to get enum type from QVariant and insert it in QVariant::value()? – krizajb Nov 20 '13 at 15:59
  • What do you mean? QVariant::value() already does return the enum type. – Taylor Brandstetter Nov 20 '13 at 16:39
  • I wish to use this in for loop and bind the property to a widget, so would need to have some kind of general enum property converter. Ps: Added Q_DECLARE_METATYPE, doesn't help but it's needed for the conversion. – krizajb Nov 21 '13 at 08:10

2 Answers2

1

There were a few mistakes on the code that prevent it from compiling:

  1. Using Q_OBJECT without inheriting from QObject.
  2. qRegisterMetaType is not needed if you use Q_ENUM (which I used to replace Q_ENUMS, which is the old version, deprecated in 5.5).
  3. qRegisterMetaTypeStreamOperators was being passed an int as template argument instead of the type to register, and the argument to the function (not template argument) should be a string, which is optional anyway; but not a type.

Full source:

#include <QtCore> // Just for the test. Use more fine grained includes.

/* Interface class */
class IFoo
{
Q_GADGET
public:

  enum ColorType
  {
    COLOR_RED = 0,
    COLOR_BLUE
  };
  Q_ENUM(ColorType)

  virtual QString Name(void) const = 0;
};

class Foo : public QObject, public IFoo
{
Q_OBJECT
public:
  Foo(void) 
  {
    qRegisterMetaTypeStreamOperators<IFoo::ColorType>();
  }
  virtual QString Name(void) const { return _name; }

  void SetColor(ColorType color) { _color = color; }
  ColorType Color(void) const { return _color; }
  QString ColorString(void) const { return _color == IFoo::COLOR_RED ? "Red" : "Blue"; }

  Q_PROPERTY(IFoo::ColorType Color READ Color WRITE SetColor)
  Q_PROPERTY(QString ColorString READ ColorString)

private:
  ColorType _color;
  QString _name;
};

int main (int argc, char **argv) {
  QCoreApplication app(argc, argv);

  Foo f;
  f.SetColor(IFoo::COLOR_RED);

  qDebug() << f.property("Color"); // Returns QVariant(IFoo::ColorType, ) 
  qDebug() << f.property("ColorString"); // Returns QString(Red)
  // Now returns:
  // QVariant(IFoo::ColorType, "COLOR_RED")
  // QVariant(QString, "Red")
}

#include "main.moc"
0

It looks like that moc tool is unable to generate strings for respective values. IMO problem is typedef. Try simple enum inside of class:

enum ColorType {
  COLOR_RED = 0,
  COLOR_BLUE
};

Or typedef with enum keyword:

typedef enum {
  COLOR_RED = 0,
  COLOR_BLUE
} ColorType;

I'm pretty sure that missing enum keyword confuses the moc tool.

Marek R
  • 32,568
  • 6
  • 55
  • 140
  • no enum keyword was a typo, trying out without typedef .. same, i guess i have to use StringWrapper. – krizajb Nov 21 '13 at 07:24