Object::property ( const char * name) const, возвращающий пустой QVariant

Мой класс имеет свойство enum, я хочу получить доступ к этому свойству, используя QObject*, При звонке QVariant QObject::property ( const char * name ) const возвращаемое значение пусто QVariant перечислимого типа.

Рассмотрим следующий код:

/* 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)
}

Почему свойство возвращает пустое значение QVariant? Свойство String wrapper работает как надо.

2 ответа

В коде было несколько ошибок, которые мешали его компиляции:

  1. Использование Q_OBJECT без наследования от QObject.
  2. qRegisterMetaTypeне требуется, если вы используете Q_ENUM (который я использовал для замены Q_ENUMS, старой версии, объявленной устаревшей в версии 5.5).
  3. qRegisterMetaTypeStreamOperatorsпередавалось целое число в качестве аргумента шаблона вместо регистрируемого типа, а аргумент функции (не аргумент шаблона) должен быть строкой, что в любом случае необязательно; но не тип.

Полный источник:

      #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"

Похоже, что инструмент moc не может генерировать строки для соответствующих значений. ИМО проблема typedef, Попробуй просто enum внутри класса:

enum ColorType {
  COLOR_RED = 0,
  COLOR_BLUE
};

Или же typedef с enum ключевое слово:

typedef enum {
  COLOR_RED = 0,
  COLOR_BLUE
} ColorType;

Я уверен, что отсутствует enum ключевое слово смущает инструмент moc.

Другие вопросы по тегам