【问题标题】:Object::property ( const char * name ) const returning empty QVariantObject::property ( const char * name ) const 返回空 QVariant
【发布时间】:2013-11-20 14:03:28
【问题描述】:

我的班级有枚举属性,我希望使用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 值?字符串包装器属性可以正常工作。

【问题讨论】:

  • 真的是空的吗?您是否尝试过调用 QVariant::value<:color>()?另外,您是否尝试过使用 Q_DECLARE_METATYPE?
  • 看来你是对的 .. QVariant::value<:color>() 返回了正确的 int 值。不幸的是,这对我没有多大帮助,或者是否可以从 QVariant 获取枚举类型并将其插入 QVariant::value()?
  • 什么意思? QVariant::value<:color>() 已经返回枚举类型。
  • 我希望在 for 循环中使用它并将属性绑定到小部件,因此需要某种通用枚举属性转换器。 Ps:加了Q_DECLARE_METATYPE,没用但是转换需要用到。

标签: qt enums qproperty qgadget


【解决方案1】:

代码中有一些错误导致无法编译:

  1. 使用 Q_OBJECT 而不从 QObject 继承。
  2. qRegisterMetaType 如果你使用 Q_ENUM 就不需要了(我用它来代替 Q_ENUMS,它是旧版本,在 5.5 中已弃用)。
  3. qRegisterMetaTypeStreamOperators 被传递一个 int 作为模板参数而不是要注册的类型,并且函数的参数(不是模板参数)应该是一个字符串,无论如何这是可选的;但不是类型。

完整来源:

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

【讨论】:

    【解决方案2】:

    看起来 moc 工具无法为各个值生成字符串。 IMO 问题是typedef。 在课堂内尝试简单的enum

    enum ColorType {
      COLOR_RED = 0,
      COLOR_BLUE
    };
    

    typedefenum 关键字:

    typedef enum {
      COLOR_RED = 0,
      COLOR_BLUE
    } ColorType;
    

    我很确定缺少 enum 关键字会使 moc 工具感到困惑。

    【讨论】:

    • no enum 关键字是错字,尝试不使用 typedef .. 同样,我想我必须使用 StringWrapper。
    猜你喜欢
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多