Search code examples
qt5qtreeviewqcheckbox

QTreeView checkbox color


I'm trying to add color to the checkboxes in a QTreeView, like so

Colored checkboxes

I switched from a QStyledItemDelegate to a QItemDelegate to have a better control on the drawing process, mostly for the drawCheck method. I can't get the painter to draw the colors I want though. Using css, I succeeded in changing the color of all checkboxes, but I need to choose the colors depending on some properties (unimportant here). Modifying the QStyle of the QTreeView may work but I will have the same "unique color" problem.

Modifying the painter or the option parameters do nothing.

painter->setPen(aRandomColor);
auto coloredOption = option;
coloredOption.backgroundBrush.setColor(aRandomColor);
QItemDelegate::drawCheck(painter, coloredOption, rect, state);

I understand that I can handle the complete drawing process in my own drawCheck without calling QItemDelegate::drawCheck

const auto color = wathever;
draw square outline using color
draw filled square using color
// Do NOT call QItemDelegate::drawCheck(...)

but this will force an uniform feel on all OSes. Is there no way to ask for a background color? Like... paint what you were going to paint, but do it using {color}"?


Solution

  • I tested all the members I could find, to no avail. So I did what I didn't want to do: handle the drawing process myself.

    void ActionsItemDelegate::drawCheck(QPainter *painter, ...) {
        if (thisCheckboxNeedsColoring) {
            painter->setPen(dynamicColor);
    #ifdef __APPLE__
            painter->setRenderHint(QPainter::Antialiasing);
            QPainterPath path;
            path.addRoundedRect(QRectF(rect.adjusted(3, 3, -4, -3)), 1.0, 1.0);
            painter->fillPath(path, color);
            painter->drawPath(path);
            if (state != Qt::Unchecked)
            {
              painter->fillRect(rect.adjusted(5, 8, -6, -8), Qt::white);
            }
    #else
            painter->drawRect(rect.adjusted(0, 0, -1, -1));
            if (state != Qt::Unchecked)
            {
              painter->fillRect(rect.adjusted(3, 3, -3, -3), color);
            }
    #endif
        } else {
            QItemDelegate::drawCheck(painter, option, rect, state);
        }
    }
    

    Of course, this doesn't take into account the styles or themes that Windows, Linux and macOS provide. I have no solution to this problem. I'm still open to better solutions!