[Qt-interest] Styling QStyledItemDelegate checkboxes in a QAbstractItemView with Qt Style Sheets

RJ Ryan rryan at mit.edu
Fri Oct 22 10:37:19 CEST 2010


Hello all,

I have a QTableView in which I use the Qt::CheckStateRole to show checkboxes
in one of the columns. How can I style these checkboxes with Qt style
sheets?

I have tried the following selectors:
- QCheckBox::indicator
- QTableView QCheckBox::indicator
- QTableView::item QCheckBox::indicator
- QTableView::item::indicator

Once I select the indicator, I give it a rule like so:

{
  image: url(:/foo.png);
}

None of the above selectors work. I've confirmed that the same settings work
fine on a regular QCheckBox that is not in my table.

I've tried to dig through the Qt source to find out how the checkbox is
being rendered. It looks to me like QStyledItemDelegate checks for the flags
to see if Qt::ItemIsUserCheckable, and then checks the Qt::CheckStateRole of
the cells. If it turns out the item is checkable, then it paints the widget
like so:

qstyleditemdelegate.cpp:422
const QWidget *widget = QStyledItemDelegatePrivate::widget(option);
QStyle *style = widget ? widget->style() : QApplication::style();
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);

Looking at QStyleSheetStyle::drawControl, I can see that
QStyle::CE_ItemViewItem is handled like so:

qstylesheetstyle.cpp:3952
QRenderRule subRule = renderRule(w, opt, PseudoElement_ViewItem);
if (subRule.hasDrawable() || hasStyleRule(w, PseudoElement_Indicator)) {
    QStyleOptionViewItemV4 optCopy(*vopt);
    subRule.configurePalette(&optCopy.palette, vopt->state &
QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text,
                             vopt->state & QStyle::State_Selected ?
QPalette::Highlight : QPalette::Base);
    QWindowsStyle::drawControl(ce, &optCopy, p, w);
} else {
    QStyleOptionViewItemV4 voptCopy(*vopt);
    subRule.configurePalette(&voptCopy.palette, QPalette::Text,
QPalette::NoRole);
    baseStyle()->drawControl(ce, &voptCopy, p, w);
}

>From this, it appears that the QAbstractItemView::item is checked for a
drawable (e.g. background-image?) and also if the widget itself has an
::indicator style, then it is passed through QWindowsStyle::drawControl(),
while otherwise it is passed through baseStyle()->drawControl().

Since no other styles (on my platform) handle CE_ItemViewItem, this makes it
to QCommonStyle. The handling for CE_ItemViewItem in QCommonStyle draws the
check-box like this:

proxy()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, p,
widget);

I don't know this code so well, so I'm assuming proxy() goes right back to
the top of the chain of styles, back to QStyleSheetStyle. drawPrimitive()
for QStyleSheetStyle with PE_IndicatorViewItemCheck sets pseudoElement to
PseudoElement_ViewItemIndicator and then does this:


qstylesheetstyle.cpp:4398
if (pseudoElement != PseudoElement_None) {
    QRenderRule subRule = renderRule(w, opt, pseudoElement);
    if (subRule.hasDrawable()) {
        subRule.drawRule(p, rect);
    } else {
        baseStyle()->drawPrimitive(pe, opt, p, w);
    }
}

So it looks to me like this checkbox should be rendered with the rule
indicated by PseudoElement_ViewItemIndicator. From the PseudoElement info
structure, I can tell that the selector for this is "indicator". This leads
me to believe that a selector like these should work:

QTableView::item::indicator
or
QTableView::item::indicator::checked

I've tried these and none of them seem to work. I'm using Qt 4.6.2 on Ubuntu
10.04, so I'm not sure if this is a bug or not. I've reached the limit of my
knowledge of how QStyle works, so it'd be really helpful if someone who
knows what is going on here could help me out.

Thanks for your time,
RJ Ryan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20101022/d359a709/attachment.html 


More information about the Qt-interest-old mailing list