【问题标题】:How to convert enum to QString?如何将枚举转换为 QString?
【发布时间】:2016-03-20 19:09:46
【问题描述】:

我正在尝试使用 Qt 反射将枚举转换为 QString。

以下是部分代码:

class ModelApple
{
    Q_GADGET
    Q_ENUMS(AppleType)
public:
    enum AppleType {
      Big,
      Small
    }
}

这是我想做的:

convertEnumToQString(ModelApple::Big)

返回"Big"

这可能吗? 如果您对convertEnumToQString有任何想法,请分享

【问题讨论】:

    标签: c++ qt enums


    【解决方案1】:

    以下内容应该可以帮助您:

    QString convertEnumToQString(ModelApple::AppleType type) {
        const QMetaObject metaObject = ModelApple::staticMetaObject;
        int enumIndex = metaObject.indexOfEnumerator("AppleType");
        if(enumIndex == -1) {
            /* The enum does not contain the specified enum */
            return "";
        }
        QMetaEnum en = metaObject.enumerator(enumIndex);
        return QString(en.valueToKey(type));
    }
    

    【讨论】:

    • 你为什么不加入enumStringenumString = en.valueToKey(type);的声明,它将只调用1个构造函数而不是1个构造函数和1个operator =。此外,我们可以使用-1 消除检查,因为我们可以确定该枚举存在。
    • 所以我必须指定枚举器“AppleType”?
    • @Danh 是的,你可以这样做。我的实际代码是一个模板函数,它接受枚举名称和枚举值以返回字符串。我对其进行了修改以回答问题。我的用法是string = convertEnumToQString<ModelApple>("AppleType", ModelApple::Big);,所以我需要检查一个有效的枚举并断言是否对调试无效。另外我在返回之前断言,因此首先分配然后返回的原因(纯粹是为了调试)。
    • 我明白了模板的重点。关于声明、赋值、返回,我还是觉得我们不应该多走一步,
    • @user3308570 不幸的是,是的,除非你有 Qt 5.5(然后你可以使用其他答案),这就是为什么我建议添加检查以防你将来决定更改枚举的名称。
    【解决方案2】:

    怎么样:

    QString convertEnumToQString(ModelApple::AppleType type)
    {
        const QMetaObject &mo = ModelApple::staticMetaObject;
        int index = mo.indexOfEnumerator("AppleType");
        QMetaEnum metaEnum = mo.enumerator(index);
        return metaEnum.valueToKey(type);
    }
    

    更新:对于 Qt 5.5,请参阅 this answer

    【讨论】:

      【解决方案3】:

      您需要使用Q_ENUM 宏,它向元对象系统注册一个枚举类型。

      enum AppleType {
        Big,
        Small
      };
      Q_ENUM(AppleType)
      

      现在您可以使用QMetaEnum 类来访问有关枚举器的元数据。

      QMetaEnum metaEnum = QMetaEnum::fromType<ModelApple::AppleType>();
      qDebug() << metaEnum.valueToKey(ModelApple::Big);
      

      这是此类实用程序的通用模板:

      template<typename QEnum>
      std::string QtEnumToString (const QEnum value)
      {
        return std::string(QMetaEnum::fromType<QEnum>().valueToKey(value));
      }
      

      【讨论】:

      • QMetaEnum::fromType&lt;T&gt; 在 Qt 5 中可用,在 Qt 4 中不存在。您应该添加此注释。顺便说一句,我不建议使用QMetaEnum::key,因为它以index为参数,他怎么声明enum AppleType { Big = 2, Small}
      • 从文档看来,这实际上仅适用于 Qt 5.5,因此我仍然需要在我给出的答案中使用我的方法(即将更新我的代码但必须使用 Qt 5.4现在)。
      • 'keyToValue()' 可以反过来:从字符串中获取枚举值!
      • 我得到了这个:未定义的对 MyClass::staticMetaObject 的引用。我从 Q_ENUM 的官方页面复制了示例。
      【解决方案4】:

      我遇到了同样的问题,这就是我解决它的方法。这尤其适用于 Qt 4.8

      QString string = enumToString(ModelApple::Big);
      
      QString ModelApple::enumToString(AppleType apple)
      {
          int index = metaObject()->indexOfEnumerator("AppleType");
          QMetaEnum metaEnum = metaObject()->enumerator(index);
          return metaEnum.valueToKey(apple);
      }
      

      【讨论】:

        【解决方案5】:

        在强大的 QVariant 的帮助下,发现了更优雅的方式(Qt 5.9),只需一行。

        将枚举转为字符串:

        QString theBig = QVariant::fromValue(ModelApple::Big).toString();
        

        也许你不再需要 QMetaEnum。

        这里的示例代码:

        ModelApple(无需申领 Q_DECLARE_METATYE)

        class ModelApple : public QObject
        {
            Q_OBJECT
        public:
            enum AppleType {
              Big,
              Small
            };
            Q_ENUM(AppleType)
            explicit ModelApple(QObject *parent = nullptr);
        };
        

        我创建了一个小部件应用程序,在那里调用 QVaraint 函数:

        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        #include <modelapple.h>
        #include <QDebug>
        
        MainWindow::MainWindow(QWidget *parent) :
            QMainWindow(parent),
            ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
        
            QString s = QVariant::fromValue(ModelApple::Big).toString();
            qDebug() << s;
        
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        

        您可以看到我尝试在控制台上输出字符串,这确实做到了:

        抱歉,我在某个项目中成功尝试了反向转换,但这次我遇到了编译错误。所以我决定从我的答案中删除它。

        【讨论】:

        • 感谢回答,貌似方法需要加Q_DECLARE_METATYPE(ModelApple::AppleType),甚至加了make编译成功,结果是空字符串。能否请您发布此示例代码?
        • 对于任何为此解决方案苦苦挣扎的人:您需要 Q_OBJECT 和 Q_ENUM。此外,您的枚举必须是公开的。
        • @Cheesi 你不需要Q_OBJECT: Q_GADGET 就足够了(除非你真的在做一个QObject)。
        【解决方案6】:

        对于全局 Enum 声明,请在任何头文件中使用:

        namespace YourNamespace {
        
        Q_NAMESPACE
        
        enum YourEnum: int {
        
            EnumValue1,
            EnumValue2
        };
        Q_ENUM_NS(YourEnum)
        
        }
        

        这是你想要获取枚举描述的地方:

        QMetaEnum metaEnum = QMetaEnum::fromType<YourEnum>();
        qDebug() << "Enum description: " << metaEnum.name() << "::" << metaEnum.valueToKey(YourEnum::EnumValue2);
        

        【讨论】:

        • 多年来我曾多次尝试让这个工作,最近我尝试了你的解决方案,并且成功了!诀窍是将我的“全局”枚举(即:不包含在类中)包装在命名空间内。谢谢!
        • 这样一个有用的答案。谢谢!!
        猜你喜欢
        • 1970-01-01
        • 2021-05-07
        • 2010-09-06
        • 1970-01-01
        • 1970-01-01
        • 2020-08-21
        • 2021-01-04
        相关资源
        最近更新 更多