我已经对这个主题进行了很多搜索,并且已经找到了一些方法,但是我遇到了一些错误,我找不到原因。
想法是使用 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 的未定义引用
包含
QMetaEnum
并从 QObject 派生通常可以达到目的:
#include <QMetaEnum>
class Planet : public QObject
{
Q_OBJECT
public:
其他一切看起来都很好(乍一看)。
对此只有两种可能的解释:
moc
实用程序来处理包含 Planet
的头文件(错误的时间戳阻止它第二次执行,并且存在旧版本的 moc_planet.h
,文件未添加到项目中并且未添加到项目中) makefile 规则中没有,头文件重复)
编译器针对
Planet
类优化了空 vtable。在这种情况下,任何未声明为内联的虚拟函数,例如~Planet();
在 .cpp 中定义主体即可。
我找到了问题的答案。
当我研究这个 vtable 问题时,我发现了这篇文章。 C++ - 对`vtable
的未定义引用我已经尝试过并从类中删除了 Q_Object 宏。 然后两个错误都消失了
编辑:这并不能解决问题!但您可以在这里找到解决方案: QMetaEnum 不读取枚举中的键 当我发表第二篇文章时,我不知道这两个问题是相互关联的。
这是一个对我有用的解决方案:
注意:我使用
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");