When using Qt to develop a graphical interface, it is inevitable that we have to redraw various controls. Note how I drew pe_framefocusRect.

PE_FrameFocusRect

To draw the checkbox for QListWidgetItem, use QStyle:: DrawPrimitive and QStyle:: Pe_FramefocusRect. And you need to create a QStyLeoptionFocusRect object that contains a member variable QColor BackgroundColor. According to the Qt documentation, I initially thought that by changing the backgroundColor, I could simply change the backgroundColor of QStyle:: Pe_FramefocusRect. However, this is not the case. The use of this backgroundColor member depends on the implementation of the different QStyle.

QColor QStyleOptionFocusRect::backgroundColor


This variable holds the background color on which the focus rectangle is being drawn


The default value is an invalid color with the RGB value (0, 0, 0). An invalid color is a color that is not properly set up for the underlying window system.

When I’m drawing QStyle: : PE_FrameFocusRect experienced a failure, no matter QStyleOptionFocusRect: : backgroundColor why color is useless. Later I realized that QStyle:: DrawPrimitive is implemented quite differently in different styles. My project is Fusion style, so there is no use QStyleOptionFocusRect: : backgroundColor. Here is a comparison of QStyle:: PE_FramefocusRect implementation in QWindowsStyle versus QFusionStyle.

qfusionstyle.cpp

QColor highlight(const QPalette &pal) const { if (isMacSystemPalette(pal)) return QColor(60, 140, 230); return pal.color(QPalette::Highlight); } QColor highlightedOutline(const QPalette &pal) const { QColor highlightedOutline = highlight(pal).darker(125); if (highlightedOutline.value() > 160) highlightedOutline.setHsl(highlightedOutline.hue(), highlightedOutline.saturation(), 160); return highlightedOutline; } void QFusionStyle::drawPrimitive( PrimitiveElement elem, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { QColor highlightedOutline = d->highlightedOutline(option->palette); / /... case PE_FrameFocusRect: if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(option)) { //### check for d->alt_down if (! (fropt->state & State_KeyboardFocusChange)) return; QRect rect = option->rect; painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); Painter - > translate (0.5, 0.5); QColor fillcolor = highlightedOutline; fillcolor.setAlpha(80); painter->setPen(fillcolor.darker(120)); fillcolor.setAlpha(30); QLinearGradient gradient(rect.topLeft(), rect.bottomLeft()); gradient.setColorAt(0, fillcolor.lighter(160)); gradient.setColorAt(1, fillcolor); painter->setBrush(gradient); painter->drawRoundedRect(option->rect.adjusted(0, 0, -1, -1), 1, 1); painter->restore(); } break; / /... }

qwindowsstyle.cpp

case PE_FrameFocusRect: if (const QStyleOptionFocusRect *fropt = qstyleoption_cast<const QStyleOptionFocusRect *>(opt)) { //### check for d->alt_down if (! (fropt->state & State_KeyboardFocusChange) && ! proxy()->styleHint(SH_UnderlineShortcut, opt)) return; QRect r = opt->rect; p->save(); p->setBackgroundMode(Qt::TransparentMode); QColor bg_col = fropt->backgroundColor; if (! bg_col.isValid()) bg_col = p->background().color(); // Create an "XOR" color. QColor patternCol((bg_col.red() ^ 0xff) & 0xff, (bg_col.green() ^ 0xff) & 0xff, (bg_col.blue() ^ 0xff) & 0xff); p->setBrush(QBrush(patternCol, Qt::Dense4Pattern)); p->setBrushOrigin(r.topLeft()); p->setPen(Qt::NoPen); p->drawRect(r.left(), r.top(), r.width(), 1); // Top p->drawRect(r.left(), r.bottom(), r.width(), 1); // Bottom p->drawRect(r.left(), r.top(), 1, r.height()); // Left p->drawRect(r.right(), r.top(), 1, r.height()); // Right p->restore(); } break;

So in the Fusion style, drawing QStyle:: PE_FramefocusRect requires two points. First, you need to set the color of QStyleOption::QPalette ::Highlight in QStyleOption::QPalette; The second is to set the state_keyboardFocusChange bit in QstyleOption ::state. For the same reason, Windows style should also refer to the source code conditions.