有没有办法获得QColor的智能名称?

jpo*_*o38 3 c++ qt

我通过名称(“红色”,“绿色”)创建颜色,但是稍后当我询问其名称时,就会获得RGB信息。是否有没有办法检索颜色名称(显然,它们不能全都有名称)。

#include <QColor>
#include <iostream>

int main( int argc, char* argv[] )
{
    QColor color( "red" );
    std::cout << color.name().toStdString();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出“#ff0000”,我希望输出“红色”。

Max*_*hof 5

我从文档中看到的唯一方法是遍历Qt知道的所有命名颜色(由提供QColor::colorNames()),将每种QColor颜色转换为a 并检查颜色是否匹配(有一个operator==for QColor适用)。

如果要重复执行此操作,建议使用某种类型的地图,而不要不断进行线性搜索。QColor不会直接借给自己作为map键(no operator<和no hash函数),但是我们可以使用其底层的RGBA值。如果我们为此编写自定义代码,则最好避免使用(出于我们的目的)效率低下的map / unordered_map实现,并在排序后的向量上使用二进制搜索,从而正确地获得性能方面的信息:

// Lookup class that is only accessible from getColorName free function.
class NamedQColorLookup
{
private:
    NamedQColorLookup()
    {
        auto keyList = QColor::colorNames();

        // Simple implementation for filling _keys and _values using std::map.
        // Alternatively, sort two vectors at once, for example like
        // /sf/ask/1195202711/
        // But that's less readable and (since it's only done once) has no meaningful performance impact.
        std::map<std::uint64_t, QString> colorMap;
        for (const auto& key : keyList)
            colorMap.emplace(QColor(key).rgba64(), key);

        // Convert to faster and smaller vector lookup.
        _keys.reserve(colorMap.size());
        _values.reserve(colorMap.size());
        for (const auto& [key, value] : colorMap)
        {
            _keys.emplace_back(key);
            _values.emplace_back(value);
        }
    }

    QString getName(const QColor& color) const
    {
        auto rgba = color.rgba64();
        // Binary search for the RGBA value.
        auto [notLessThan, greaterThan] = std::equal_range(_keys.begin(), _keys.end(), rgba);

        // If this is not a named color, return the RGB code instead.
        if (notLessThan == greaterThan)
            return color.name();

        // We found a matching ARGB value, obtain its index.
        auto index = std::distance(_keys.begin(), notLessThan);
        return _values[index];
    }

    std::vector<std::uint64_t> _keys;
    std::vector<QString> _values; // ...or some kind of string view if you want.

    friend QString getColorName(const QColor& color);
};

// The interface for color -> name lookups.
QString getColorName(const QColor& color)
{
    static NamedQColorLookup lookup;
    return lookup.getName(color);
}
Run Code Online (Sandbox Code Playgroud)

我们可以使用a std::vector<std::pair<std::uint64_t, QString>>而不是两个单独的向量,但这会使二进制搜索变慢(更多的缓存未命中)。

在这里玩:https : //godbolt.org/z/z1fgyc