Make the defaultSectionSize property of QHeaderView style dependent

Add new enum items PM_HeaderDefaultSectionSizeHorizontal and
PM_HeaderDefaultSectionSizeVertical to QStyle and get corresponding
values in QHeaderView. This way we get rid of some magic constants in
QHeaderView and we can have reasonable values for the default section
size for high-DPI displays.

[ChangeLog][QtWidgets][QHeaderView] Default section size is now style-dependent by default.

[ChangeLog][QtWidgets][QHeaderView] Added resetDefaultSectionSize().

Change-Id: I44e152c5cf0bec1e5d78e1e62f47a2d1f761dfbf
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
This commit is contained in:
Alexander Volkov 2014-11-12 17:13:22 +03:00
parent 6386bafb40
commit 53022e04bb
7 changed files with 95 additions and 3 deletions

View File

@ -1515,6 +1515,11 @@ void QHeaderView::setCascadingSectionResizes(bool enable)
This property only affects sections that have \l Interactive or \l Fixed
as their resize mode.
By default, the value of this property is style dependent.
Thus, when the style changes, this property updates from it.
Calling setDefaultSectionSize() stops the updates, calling
resetDefaultSectionSize() will restore default behavior.
\sa setSectionResizeMode(), minimumSectionSize
*/
int QHeaderView::defaultSectionSize() const
@ -1531,6 +1536,15 @@ void QHeaderView::setDefaultSectionSize(int size)
d->setDefaultSectionSize(size);
}
void QHeaderView::resetDefaultSectionSize()
{
Q_D(QHeaderView);
if (d->customDefaultSectionSize) {
d->updateDefaultSectionSizeFromStyle();
d->customDefaultSectionSize = false;
}
}
/*!
\since 4.2
\property QHeaderView::minimumSectionSize
@ -2209,6 +2223,10 @@ bool QHeaderView::event(QEvent *e)
resizeSections();
}
break; }
case QEvent::StyleChange:
if (!d->customDefaultSectionSize)
d->updateDefaultSectionSizeFromStyle();
break;
default:
break;
}
@ -3465,6 +3483,7 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size)
executePostedLayout();
invalidateCachedSizeHint();
defaultSectionSize = size;
customDefaultSectionSize = true;
if (state == QHeaderViewPrivate::ResizeSection)
preventCursorChangeInSetOffset = true;
for (int i = 0; i < sectionItems.count(); ++i) {
@ -3485,6 +3504,17 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size)
viewport->update();
}
void QHeaderViewPrivate::updateDefaultSectionSizeFromStyle()
{
Q_Q(QHeaderView);
if (orientation == Qt::Horizontal) {
defaultSectionSize = q->style()->pixelMetric(QStyle::PM_HeaderDefaultSectionSizeHorizontal, 0, q);
} else {
defaultSectionSize = qMax(q->minimumSectionSize(),
q->style()->pixelMetric(QStyle::PM_HeaderDefaultSectionSizeVertical, 0, q));
}
}
void QHeaderViewPrivate::recalcSectionStartPos() const // linear (but fast)
{
int pixelpos = 0;
@ -3632,6 +3662,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << sectionItems;
out << resizeContentsPrecision;
out << customDefaultSectionSize;
}
bool QHeaderViewPrivate::read(QDataStream &in)
@ -3708,6 +3739,14 @@ bool QHeaderViewPrivate::read(QDataStream &in)
if (in.status() == QDataStream::Ok) // we haven't read past end
resizeContentsPrecision = tmpint;
bool tmpbool;
in >> tmpbool;
if (in.status() == QDataStream::Ok) { // we haven't read past end
customDefaultSectionSize = tmpbool;
if (!customDefaultSectionSize)
updateDefaultSectionSizeFromStyle();
}
return true;
}

View File

@ -51,7 +51,7 @@ class Q_WIDGETS_EXPORT QHeaderView : public QAbstractItemView
Q_PROPERTY(bool highlightSections READ highlightSections WRITE setHighlightSections)
Q_PROPERTY(bool stretchLastSection READ stretchLastSection WRITE setStretchLastSection)
Q_PROPERTY(bool cascadingSectionResizes READ cascadingSectionResizes WRITE setCascadingSectionResizes)
Q_PROPERTY(int defaultSectionSize READ defaultSectionSize WRITE setDefaultSectionSize)
Q_PROPERTY(int defaultSectionSize READ defaultSectionSize WRITE setDefaultSectionSize RESET resetDefaultSectionSize)
Q_PROPERTY(int minimumSectionSize READ minimumSectionSize WRITE setMinimumSectionSize)
Q_PROPERTY(int maximumSectionSize READ maximumSectionSize WRITE setMaximumSectionSize)
Q_PROPERTY(Qt::Alignment defaultAlignment READ defaultAlignment WRITE setDefaultAlignment)
@ -156,6 +156,7 @@ public:
int defaultSectionSize() const;
void setDefaultSectionSize(int size);
void resetDefaultSectionSize();
int minimumSectionSize() const;
void setMinimumSectionSize(int size);

View File

@ -84,6 +84,7 @@ public:
cascadingResizing(false),
resizeRecursionBlock(false),
allowUserMoveOfSection0(true), // will be false for QTreeView and true for QTableView
customDefaultSectionSize(false),
stretchSections(0),
contentsSections(0),
minimumSectionSize(-1),
@ -155,8 +156,7 @@ public:
inline void setDefaultValues(Qt::Orientation o) {
orientation = o;
defaultSectionSize = (o == Qt::Horizontal ? 100
: qMax(q_func()->minimumSectionSize(), 30));
updateDefaultSectionSizeFromStyle();
defaultAlignment = (o == Qt::Horizontal
? Qt::Alignment(Qt::AlignCenter)
: Qt::AlignLeft|Qt::AlignVCenter);
@ -275,6 +275,7 @@ public:
bool cascadingResizing;
bool resizeRecursionBlock;
bool allowUserMoveOfSection0;
bool customDefaultSectionSize;
int stretchSections;
int contentsSections;
int defaultSectionSize;
@ -321,6 +322,7 @@ public:
void removeSectionsFromSectionItems(int start, int end);
void resizeSectionItem(int visualIndex, int oldSize, int newSize);
void setDefaultSectionSize(int size);
void updateDefaultSectionSizeFromStyle();
void recalcSectionStartPos() const; // not really const
inline int headerLength() const { // for debugging

View File

@ -4592,6 +4592,12 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
case PM_HeaderGripMargin:
ret = int(QStyleHelper::dpiScaled(4.));
break;
case PM_HeaderDefaultSectionSizeHorizontal:
ret = int(QStyleHelper::dpiScaled(100.));
break;
case PM_HeaderDefaultSectionSizeVertical:
ret = int(QStyleHelper::dpiScaled(30.));
break;
case PM_TabBarScrollButtonWidth:
ret = int(QStyleHelper::dpiScaled(16.));
break;

View File

@ -1472,6 +1472,11 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value PM_TreeViewIndentation The indentation of items in a tree view.
This enum value has been introduced in Qt 5.4.
\value PM_HeaderDefaultSectionSizeHorizontal The default size of sections
in a horizontal header. This enum value has been introduced in Qt 5.5.
\value PM_HeaderDefaultSectionSizeVertical The default size of sections
in a vertical header. This enum value has been introduced in Qt 5.5.
\value PM_CustomBase Base value for custom pixel metrics. Custom
values must be greater than this value.

View File

@ -550,6 +550,9 @@ public:
PM_SubMenuOverlap,
PM_TreeViewIndentation,
PM_HeaderDefaultSectionSizeHorizontal,
PM_HeaderDefaultSectionSizeVertical,
// do not add any values below/greater than this
PM_CustomBase = 0xf0000000
};

View File

@ -176,6 +176,7 @@ private slots:
void moveSectionAndRemove();
void saveRestore();
void defaultSectionSizeTest();
void defaultSectionSizeTestStyles();
void defaultAlignment_data();
void defaultAlignment();
@ -1679,6 +1680,41 @@ void tst_QHeaderView::defaultSectionSizeTest()
QVERIFY(hv->sectionSize(2) == 0); // section is hidden. It should not be resized.
}
class TestHeaderViewStyle : public QProxyStyle
{
public:
TestHeaderViewStyle() : horizontalSectionSize(100) {}
int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE
{
if (metric == QStyle::PM_HeaderDefaultSectionSizeHorizontal)
return horizontalSectionSize;
else
return QProxyStyle::pixelMetric(metric, option, widget);
}
int horizontalSectionSize;
};
void tst_QHeaderView::defaultSectionSizeTestStyles()
{
TestHeaderViewStyle style1;
TestHeaderViewStyle style2;
style1.horizontalSectionSize = 100;
style2.horizontalSectionSize = 200;
QHeaderView hv(Qt::Horizontal);
hv.setStyle(&style1);
QCOMPARE(hv.defaultSectionSize(), style1.horizontalSectionSize);
hv.setStyle(&style2);
QCOMPARE(hv.defaultSectionSize(), style2.horizontalSectionSize);
hv.setDefaultSectionSize(70);
QCOMPARE(hv.defaultSectionSize(), 70);
hv.setStyle(&style1);
QCOMPARE(hv.defaultSectionSize(), 70);
hv.resetDefaultSectionSize();
QCOMPARE(hv.defaultSectionSize(), style1.horizontalSectionSize);
hv.setStyle(&style2);
QCOMPARE(hv.defaultSectionSize(), style2.horizontalSectionSize);
}
void tst_QHeaderView::defaultAlignment_data()
{