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.
Then you'll find that QColor::name()
also ignores the alpha channel. Here, you have to use QColor::name(QColor::HexArgb)
instead.
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.