qt

Qt enums/flags and QVariant::toString


Any value of type Qt::Alignment (flag) can be converted to a nice to read string, such as what is done below:

QString s = QVariant::fromValue<Qt::Alignment>(Qt::AlignTop | Qt::AlignLeft).toString();

That code fills s with AlignLeading|AlignTop.
That is correct in a way, as Qt::AlignLeading is a synonym for Qt::AlignLeft. I would rather get the original value than its synonym, though and apparently, the Qt team agrees as the Property editor of the Qt designer makes no mention of the synonyms.

Is there a way to get the string I want with Qt-only functionalities, i.e. without some sort of hack?


Solution

  • You can register your own converter for Qt::Alignment somewhere on application startup (I hope this is not a hack you want to avoid). Here is some example

    QMetaType::registerConverter<Qt::Alignment, QString>([](const Qt::Alignment &align) {
        static const QMap<Qt::Alignment, QString> alignMap {{Qt::AlignLeft, "AlignLeft"},
                                                              {Qt::AlignRight, "AlignRight"},
                                                              {Qt::AlignHCenter, "AlignHCenter"},
                                                              {Qt::AlignJustify, "AlignJustify"},
                                                              {Qt::AlignAbsolute, "AlignAbsolute"},
                                                              {Qt::AlignTop, "AlignTop"},
                                                              {Qt::AlignBottom, "AlignBottom"},
                                                              {Qt::AlignVCenter, "AlignVCenter"},
                                                              {Qt::AlignBaseline, "AlignBaseline"}};
        QString textResult;
        for (auto [alignKey, alignText] : alignMap.asKeyValueRange())
        {
            if (alignKey & align)
            {
                textResult.append(alignText);
                textResult.append("|");
            }
        }
    
        if (!textResult.isEmpty())
        {
            textResult.removeLast();
        }
    
        return textResult;
    });