Sign up for the KDAB Newsletter
Stay on top of the latest news, publications, events and more.
Go to Sign-up
20 February 2020
Working on color imagery for QiTissue recently, I realized we were accidentally losing the alpha channel in multiple places. For efficiency reasons, we keep colors in memory using the QRgb
type, and convert that to/from QString
for serialization purposes via QColor
as needed. Here's what I discovered about why that doesn't work, and some ways I fixed it.
Firstly, be aware there is no QRgba
in the Qt API . There is only QRgb
, for 8bit color channels. It can hold an alpha value too, despite the lack of a trailing a
in the type name. Then there is QRgba64
which uses 16bit per color channel. For our purposes, 8bit per channel is sufficient. So where do we lose the alpha channel, when QRgb
can store it in principle?
The first pitfall is QColor(QRgb)
, which calls QColor::fromRgb
internally. Both of these functions silently ignore the alpha channel of the passed QRgb
value and assume the color is fully opaque. To get around this, you have to use QColor::fromRgba
instead.
QColor toColor(QRgb colorWithAlpha)
{
// all bad: input alpha ignored, set to fully opaque
return QColor(colorWithAlpha);
return colorWithAlpha;
return QColor::fromRgb(colorWithAlpha);
// good:
return QColor::fromRgba(colorWithAlpha);
}
Then you'll find that QColor::name()
also ignores the alpha channel. Here, you have to use QColor::name(QColor::HexArgb)
instead.
QString toString(const QColor &colorWithAlpha)
{
// bad: input alpha ignored, output is e.g. #112233
return colorWithAlpha.name();
// good: output is e.g. #00112233
return colorWithAlpha.name(QColor::HexArgb);
}
Thankfully, the QColor
constructors and QColor::setName
function, which parse a string color name, won't ignore the alpha channel when you pass an '#AARRGGBB' string.
However, there is one more pitfall: When you have a QColorDialog
with QColorDialog::ShowAlphaChannel
, and listen to its currentColorChanged
signal and set a color with an alpha channel on it, a stray change signal notification will be emitted with a fully opaque color. The reason is that, internally, the color dialog will first set the RGB color components, and then in a second step will set the alpha component. But both will trigger a change notification, where the first step holds a fully opaque color. This should be fixed upstream, but thankfully for now it is easy to workaround by ignoring the signal while setting a color from the outside.
About KDAB
The KDAB Group is a globally recognized provider for software consulting, development and training, specializing in embedded devices and complex cross-platform desktop applications. In addition to being leading experts in Qt, C++ and 3D technologies for over two decades, KDAB provides deep expertise across the stack, including Linux, Rust and modern UI frameworks. With 100+ employees from 20 countries and offices in Sweden, Germany, USA, France and UK, we serve clients around the world.
Stay on top of the latest news, publications, events and more.
Go to Sign-up
Learn Modern C++
Our hands-on Modern C++ training courses are designed to quickly familiarize newcomers with the language. They also update professional C++ developers on the latest changes in the language and standard library introduced in recent C++ editions.
Learn more