使用 QMetaEnum 将枚举转换为字符串

问题描述 投票:0回答:4

我已经对这个主题进行了很多搜索,并且已经找到了一些方法,但是我遇到了一些错误,我找不到原因。

想法是使用 QMetaEnum 从枚举中读取键,以便稍后将字符串填充到组合框中。

我已经有了枚举,并且还在枚举所在的类中设置了 Q_Object 和 Q_Enum 宏。但我使用 QMetaEnum 收到“对 'Planet::metaObject() const' 的未定义引用”错误消息。

这是星球。h

#include <QMetaEnum>
class Planet
{
    Q_OBJECT
public:    
    enum PlanetTypes
    {
       Barren,Gas,Ice,Lava,Oceanic,Plasma,Storm,Temperate
    };Q_ENUM(PlanetTypes)
    Planet();
    //some getters and setters for my private member-variables
};

这是我尝试读取枚举并获取错误消息的片段。

QStringList DataModel::getPlanetTypes()
{
   QStringList PlanetTypesList;

   Planet p;
   const QMetaObject* metaObj = p.metaObject();
   QMetaEnum e = metaObj->enumerator(metaObj->indexOfEnumerator("PlanetTypes"));
   for(int i=0; i<e.keyCount();i++)
   {
        PlanetTypesList.append(e.key(i));
   }
   return PlanetTypesList;

}

错误指的是行:

QMetaEnum e = metaObj->enumerator(metaObj->indexOfEnumerator("PlanetTypes"));

我什至尝试从QObject继承planet,但它也没有解决问题。

获得一些帮助以及 QMetaEnum 用法的进一步解释会非常酷。

编辑:它还给了我一个错误:未定义引用“vtable for Planet”,如果这有助于了解此问题的来源。

编辑2: 我发现了“vtable”问题,但它也无法解决此错误。 Qt 对 vtable 的未定义引用

c++ qt enums qt5
4个回答
0
投票

包含

QMetaEnum
并从 QObject 派生通常可以达到目的:

#include <QMetaEnum>
class Planet : public QObject
    {
        Q_OBJECT
    public: 

其他一切看起来都很好(乍一看)。


0
投票

对此只有两种可能的解释:

    无论出于何种原因,都不会调用
  1. moc
    实用程序来处理包含
    Planet
    的头文件(错误的时间戳阻止它第二次执行,并且存在旧版本的
    moc_planet.h
    ,文件未添加到项目中并且未添加到项目中) makefile 规则中没有,头文件重复)

  2. 编译器针对

    Planet
    类优化了空 vtable。在这种情况下,任何未声明为内联的虚拟函数,例如
    ~Planet();
    在 .cpp 中定义主体即可。


0
投票

我找到了问题的答案。

当我研究这个 vtable 问题时,我发现了这篇文章。 C++ - 对`vtable

的未定义引用

我已经尝试过并从类中删除了 Q_Object 宏。 然后两个错误都消失了

编辑:这并不能解决问题!但您可以在这里找到解决方案: QMetaEnum 不读取枚举中的键 当我发表第二篇文章时,我不知道这两个问题是相互关联的。


0
投票

这是一个对我有用的解决方案:

注意:我使用

Q_GADGET
而不是
Q_OBJECT
,因为我只需要枚举类,而不需要
QObject
附带的元对象内容:

#include <QMetaEnum>

class PlanetTypesClass
{
  Q_GADGET
  explicit PlanetTypesClass() = default; 
public:    
  enum Value
  {
     Barren,Gas,Ice,Lava,Oceanic,Plasma,Storm,Temperate
  };
  Q_ENUM(Value)
  static auto getPlanetTypes() ->  QStringList;
    //some getters and setters for my private member-variables
private:
  static const QMetaEnum metaEnum;
};
using PlanetTypes = PlanetTypesClass::Value;

这就是枚举方面的内容。现在列出清单

const QMetaEnum PlanetTypesClass::metaEnum =
  QMetaEnum::fromType<PlanetTypes>();

static auto PlanetTypesClass::getPlanetTypes() -> QStringList
{
  QStringList planets;
  for (int i = 0; i < metaEnum.keyCount(); ++i) {
    planets << metaEnum.key(i);
  }
  return planets;
}

如果您计划在 QML 中使用枚举,则必须通过以下方式注册:

qmlRegisterUncreatableType<PlanetTypesClass>(
    "some.id.PlanetTypes",
    1,
    0,
    "PlanetTypes",
    "Not creatable as it is an enum");
© www.soinside.com 2019 - 2024. All rights reserved.