Possible QCommonStyle (QStyleSheetStyle) bug
-
While I was investigating my issue related to QTableView (QHeaderView) sort indicator alignment I possibly identified a "glitch".
In
QCommonStyle::subElementRect()
the header is handled in multiple parts, Section, Label and Indicator in general.
Issue 1
case SE_HeaderLabel: { int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget); r.setRect(opt->rect.x() + margin, opt->rect.y() + margin, opt->rect.width() - margin * 2, opt->rect.height() - margin * 2); if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { // Subtract width needed for arrow, if there is one if (header->sortIndicator != QStyleOptionHeader::None) { if (opt->state & State_Horizontal) r.setWidth(r.width() - (opt->rect.height() / 2) - (margin * 2)); // <-- logic? else r.setHeight(r.height() - (opt->rect.width() / 2) - (margin * 2)); // <-- logic? } } r = visualRect(opt->direction, opt->rect, r); break; }
Here, for me the confusion is the logic behind the
setWidth
orsetHeight
for the Header Label part. Those calculations above don't make sense. The half of the Header Section size has nothing to with the size of the Header Indicator part nor with the Header Label part overall.Instead, it could be something similar to QStyleSheetStyle SE_HeaderLabel where the Indicator rect size is properly calculated.
if (header->sortIndicator != QStyleOptionHeader::None) { const auto arrowRect = subElementRect(SE_HeaderArrow, opt, w); if (arrowRect.isValid()) { if (opt->state & State_Horizontal) r.setWidth(r.width() - arrowRect.width()); else r.setHeight(r.height() - arrowRect.height()); } }
This seems to cause label text cropping already:
Issue 2
As stated above, for the Header Label rect size the code subtracts margin and half of the section size from the overall Header Section size.
But in case a styleSheet is also used (e.g. in my other issue I mentioned) then we end up using QStyleSheetStyle SE_HeaderLabel additionally to QCommonStyle SE_HeaderLabel which means a "double subtraction".
Header Label rect logical calculation steps when styelsheet is used:
- starting size: Header Section rect size
- calculated size 1 (QCommonStyle SE_HeaderLabel): Header Section rect size - "half of section height" - margin
- calculated size 2 (QStyleSheetStyle SE_HeaderLabel): calculated size 1 - SE_HeaderArrow size
This leads to a problem where the Label text is not fully shown (and somehow the width of the section becomes bigger and root cause for that is not known as of yet):
Could anyone reconfirm this?
Not sure how to proceed with Jira bug report if these are real faults.
Thank you!
-
Update on Issue 1
I managed to test my original idea and using the "QStyleSheetStyle SE_HeaderLabel" logic for
setWidth
andsetHeight
under "QCommonStyle SE_HeaderLabel" works nicely.(aligning the indicator is still not working)
QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, const QWidget *widget) const { Q_D(const QCommonStyle); QRect r; switch (sr) { ... case SE_HeaderLabel: { int margin = QCommonStyle::proxy()->pixelMetric(PM_HeaderMargin, opt, w); r.setRect(opt->rect.x() + margin, opt->rect.y() + margin, opt->rect.width() - margin * 2, opt->rect.height() - margin * 2); if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) { // Subtract width needed for arrow, if there is one if (header->sortIndicator != QStyleOptionHeader::None) { const QRect arrowRect = subElementRect(QStyle::SE_HeaderArrow, opt, w); if (arrowRect.isValid()) { if (opt->state & QStyle::State_Horizontal) r.setWidth(r.width() - arrowRect.width()); else r.setHeight(r.height() - arrowRect.height()); } } } r = visualRect(opt->direction, opt->rect, r); break; } ...
-
Jira ticket has been raised for Issue 1: QTBUG-138495