Pregunta

Standard QListWidget draws white text of selected row on Windows XP and black on Windows 7/8. Where does it get black or white color?

I've made a custom delegate for ListView and try to draw text in a selected row, but application palette returns same colors (HighlightedText, BrightText, WindowText, Text) on WinXP and 8, while default delegate somehow draws it black or white. I've looked through Qt source and couldn't find where does it get the contrast color. QListWidget style itself returns the same color of ForegroundRole on all platforms, too.

Am I missing some way of getting correct os palette in Qt app?

¿Fue útil?

Solución

Unfortunately not all colors are readable via QPalette. Especially for the QAbstractItemView subclasses (list views, tree views…), the Windows style retrieves the colors via WinAPI and uses them directly for painting.

All relevant code should be in qtbase/src/widgets/styles/qwindowsxpstyle.cpp and qtbase/src/widgets/styles/qwindowsvistastyle.cpp, search for "pGetThemeColor”.

As Marek says, for some of these colors it’s possible to override those defaults, but it’s not possible to read them via Qt API.

Otros consejos

In case of QListWidget it is a bit complicated. Starting from lowest priority settings:

  1. Every QWidget has palette property which contains set of colors for different states and items in widget (depending on style and platform it works or not - usually it does).
  2. Style sheet can override palette, you can set those colors using CSS in text format.
  3. Data model can provide colors using receptive role value.

if you are providing a delegate then you are responsible to handle colors, if I find some pattern for that I will give you a link.

Thanks.

Anyway, it turned out that QListWidget/View delegate actually doesn't paint text - it asks style to draw a native control, and that draws contrast text somewhere deep in Qt theming engine. If pen and brush are same as in default palette, their colors may be changed to os-themed. Native drawing solved text color issue for me.

void customDelegate::paint(QPainter *painter,
    const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    // ...
    QStyleOptionViewItemV4 opt = option;
    opt.state            = opt.state & (~QStyle::State_HasFocus); // no dots
    opt.displayAlignment = Qt::AlignVCenter | Qt::AlignLeft; // or right
    opt.features         = QStyleOptionViewItemV2::HasDisplay;
    opt.text             = displayText(textGoesThere, opt.locale); // <--
    opt.rect             = option.rect;
    //...

    if (multipartDrawing) {
        if (drawingSomethingAtLeft)
            opt.viewItemPosition = QStyleOptionViewItem::Beginning;
        else if (somethingAtRight)
            opt.viewItemPosition = QStyleOptionViewItem::End;
        else
            opt.viewItemPosition = QStyleOptionViewItem::Middle;
    }
    else    opt.viewItemPosition = QStyleOptionViewItem::OnlyOne;

    owner->style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter);
    //...
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top