我通过名称(“红色”,“绿色”)创建颜色,但是稍后当我询问其名称时,我会获得RGB信息。如果有的话,没有办法检索颜色名称(显然,它们不能全都有名称)。
#include <QColor>
#include <iostream>
int main( int argc, char* argv[] )
{
QColor color( "red" );
std::cout << color.name().toStdString();
return 0;
}
这将输出“#ff0000”,我希望它输出“红色”。
答案 0 :(得分:5)
我从文档中看到的唯一方法是遍历Qt知道的所有命名颜色(由QColor::colorNames()
提供),将每种颜色转换为QColor
并检查颜色是否匹配(对于operator==
有一个QColor
可用。)
如果要重复执行此操作,建议使用某种类型的地图,而不要不断进行线性搜索。 QColor
不能直接借给自己作为映射键(没有operator<
且没有哈希函数),但是我们可以使用其底层的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
// https://stackoverflow.com/questions/17074324/how-can-i-sort-two-vectors-in-the-same-way-with-criteria-that-uses-only-one-of
// 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);
}
我们可以使用std::vector<std::pair<std::uint64_t, QString>>
来代替两个单独的向量,但这会使二进制搜索变慢(更多的缓存未命中)。
在此处使用它:https://godbolt.org/z/z1fgyc
答案 1 :(得分:2)
在我看来,这就是您要寻找的
#include <QColor>
#include <iostream>
int main( int argc, char* argv[] )
{
QColor color( "red" );
QColor cmp;
for(auto i : QColor::colorNames()) {
cmp.setNamedColor(i);
if(cmp == color)
std::cout << i.toStdString();
}
return 0;
}
请注意,任何带有该颜色名称的内置函数也可能会使用类似的循环。
作为旁注,由于使用的是Qt,因此应考虑使用qDebug而不是cout。