C++ 转换枚举值的字符串表示形式

C++ 转换枚举值的字符串表示形式,c++,qt,enums,translation,C++,Qt,Enums,Translation,是否可以使用Qt的翻译系统翻译enum(即通过QMetaEnum)的字符串表示形式 我想我需要的是某种方法来获取lupdate来提取枚举字符串进行翻译,或者在且仅当文件由lupdate处理时发出一些QT_TR_NOOP()代码,或者修改lupdate/moc本身的行为 例如,我的应用程序通过对话框向用户显示“设置”选项。所有设置都定义为Q\u属性。使用enum的选项显示为组合框,组合框的文本选项使用QMetaEnum::key()作为显示的文本。下面是一些伪代码来阐明这一点 小部件将具有一些定义

是否可以使用Qt的翻译系统翻译
enum
(即通过
QMetaEnum
)的字符串表示形式

我想我需要的是某种方法来获取
lupdate
来提取枚举字符串进行翻译,或者在且仅当文件由lupdate处理时发出一些QT_TR_NOOP()代码,或者修改
lupdate
/
moc
本身的行为

例如,我的应用程序通过对话框向用户显示“设置”选项。所有设置都定义为
Q\u属性
。使用
enum
的选项显示为组合框,组合框的文本选项使用
QMetaEnum::key()
作为显示的文本。下面是一些伪代码来阐明这一点

小部件将具有一些定义如下的
enum
属性:

class SomeWidget : public QWidget
{
    Q_OBJECT
    Q_ENUMS( Configuration );

    enum Configuration
    {
        Config_Blue = 0,
        Config_Green,
        Config_Invisible,
        Config_Backwards
    };

    Q_PROPERTY( Configuration READ Configuration WRITE SetConfiguration );
};
组合小部件的创建由单独的设置管理器完成,如下所示:

QWidget* SettingsItem::CreateWidget()
{
    const QMetaObject* pMetaObj = this->m_pWidget->metaObject();
    const QMetaProperty& rcProp = pMetaObj->property( this->m_iProp );

    QMetaEnum cEnum = rcProp.enumerator();
    if( cEnum.isValid() )
    {
        QComboBox* pRetWidget = new QComboBox;
        for( int i = 0; i < cEnum.keyCount(); ++i )
        {
            int iVal = cEnum.value( i );
            QString strKey = cEnum.key( i );  // Translate here?
            pRetWidget->addItem( strKey, iVal );
        }
    } 

    ...
    return pRetWidget;
}
QWidget*SettingsItem::CreateWidget()
{
常量QMetaObject*pMetaObj=this->m_pWidget->metaObject();
const QMetaProperty&rcProp=pMetaObj->property(this->m_iProp);
QMetaEnum cEnum=rcProp.enumerator();
if(cEnum.isValid())
{
QCOMBOX*pRetWidget=新的QCOMBOX;
对于(int i=0;iaddItem(斯尔基,伊瓦尔);
}
} 
...
返回控件;
}
“设置”对话框中的组合框显示“配置蓝色”、“配置绿色”等。我希望它能以任何当前语言显示“蓝色”、“绿色”等

对于代码的其余部分,我们使用Qt的翻译系统和
语言学家
实用程序,这非常好用。我希望能够为
enum
启用这种类型的翻译,而不必手动向代码中添加字符串文本和
tr()
。基本上,翻译人员需要的所有信息都已经存在于代码中,我只需要语言学家能够将这些枚举值识别为可翻译的。然后,当组合框被填充时,我可以调用
tr()

我想我需要的是某种方法来获取
lupdate
来提取枚举字符串进行翻译,或者在且仅当文件由lupdate处理时发出一些QT_TR_NOOP()代码,或者修改
lupdate
/
moc
本身的行为


我在想也许宏可以工作,但可能不可能。也许修改一些Qt代码是必要的?

枚举标识符一开始就不应该是用户可见的。这些标识符应该对开发人员而不是用户有意义。将它们直接公开给用户增加了代码的内部设计和用户可见行为之间的强耦合。这是最好避免的

您需要在枚举值和用户可见字符串之间进行映射。映射中的值应进行转换,并且应在重新转换后重新填充映射。例如:

class Object : public QObject
{
    Q_OBJECT
    Q_ENUMS(Configuration);
    Q_PROPERTY(Configuration READ Configuration WRITE SetConfiguration);

    enum Configuration {
        Config_Blue, Config_Green, Config_Invisible, Config_Backwards
    };
public:
    static QString toString(Configuration c) {
      switch (c) {
      case Config_Blue: return tr("Blue", "Configuration");
      case Config_Green: return tr("Green", "Configuration");
      case Config_Invisible: return tr("Invisible", "Configuration");
      case Config_Backwards: return tr("Backwards", "Configuration");
      }
    }
};

您现在可以转换配置值。

我正在定义枚举的类中使用专用函数。有帮助吗?(Qt5.13)

我把它叫做MyClass::toTrString(myEnumVal)


最初我想写一个回复,但我自己从中了解到:这似乎只是描述了如何使用QMetaEnum将键值获取为字符串。我相信这是我已经在做的事情。我想我真正需要的是lupdate拾取这些枚举字符串,以便它们可以被转换。也许我会修改我的问题,让它更清楚。如果我有700个不同枚举形式的选项,我应该为所有枚举编写这种类型的开关是的,你应该,因为它们都是面向用户的字符串。C++标识符不是真正意义上的用户。没有办法正确地给它们加标点,等等。由于依赖于用户可见的标识符,您的设计几乎一团糟。你得把自己弄得一团糟。也许所有这些都会让你意识到自己做了多少工作。您有700个可翻译字符串。你确定你的配置系统没有太过火吗?我实际上没有700个选项,我选择了一个数字。如何纠正我搞砸的这个设计呢?按照我在答案中所说的去做,而不是按照你在问题中所说的去做:)
class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = nullptr);
    enum MyEnum {
            myKey1,
            myKey2,
            ...
    };
    Q_ENUM(MyEnum)
    static QString toTrString(MyEnum t) {
        return tr(qPrintable(QVariant::fromValue(t).toString()));
    }
}