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 This property only affects sections that have \l Interactive or \l Fixed
as their resize mode. 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 \sa setSectionResizeMode(), minimumSectionSize
*/ */
int QHeaderView::defaultSectionSize() const int QHeaderView::defaultSectionSize() const
@ -1531,6 +1536,15 @@ void QHeaderView::setDefaultSectionSize(int size)
d->setDefaultSectionSize(size); d->setDefaultSectionSize(size);
} }
void QHeaderView::resetDefaultSectionSize()
{
Q_D(QHeaderView);
if (d->customDefaultSectionSize) {
d->updateDefaultSectionSizeFromStyle();
d->customDefaultSectionSize = false;
}
}
/*! /*!
\since 4.2 \since 4.2
\property QHeaderView::minimumSectionSize \property QHeaderView::minimumSectionSize
@ -2209,6 +2223,10 @@ bool QHeaderView::event(QEvent *e)
resizeSections(); resizeSections();
} }
break; } break; }
case QEvent::StyleChange:
if (!d->customDefaultSectionSize)
d->updateDefaultSectionSizeFromStyle();
break;
default: default:
break; break;
} }
@ -3465,6 +3483,7 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size)
executePostedLayout(); executePostedLayout();
invalidateCachedSizeHint(); invalidateCachedSizeHint();
defaultSectionSize = size; defaultSectionSize = size;
customDefaultSectionSize = true;
if (state == QHeaderViewPrivate::ResizeSection) if (state == QHeaderViewPrivate::ResizeSection)
preventCursorChangeInSetOffset = true; preventCursorChangeInSetOffset = true;
for (int i = 0; i < sectionItems.count(); ++i) { for (int i = 0; i < sectionItems.count(); ++i) {
@ -3485,6 +3504,17 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size)
viewport->update(); 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) void QHeaderViewPrivate::recalcSectionStartPos() const // linear (but fast)
{ {
int pixelpos = 0; int pixelpos = 0;
@ -3632,6 +3662,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << sectionItems; out << sectionItems;
out << resizeContentsPrecision; out << resizeContentsPrecision;
out << customDefaultSectionSize;
} }
bool QHeaderViewPrivate::read(QDataStream &in) 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 if (in.status() == QDataStream::Ok) // we haven't read past end
resizeContentsPrecision = tmpint; resizeContentsPrecision = tmpint;
bool tmpbool;
in >> tmpbool;
if (in.status() == QDataStream::Ok) { // we haven't read past end
customDefaultSectionSize = tmpbool;
if (!customDefaultSectionSize)
updateDefaultSectionSizeFromStyle();
}
return true; 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 highlightSections READ highlightSections WRITE setHighlightSections)
Q_PROPERTY(bool stretchLastSection READ stretchLastSection WRITE setStretchLastSection) Q_PROPERTY(bool stretchLastSection READ stretchLastSection WRITE setStretchLastSection)
Q_PROPERTY(bool cascadingSectionResizes READ cascadingSectionResizes WRITE setCascadingSectionResizes) 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 minimumSectionSize READ minimumSectionSize WRITE setMinimumSectionSize)
Q_PROPERTY(int maximumSectionSize READ maximumSectionSize WRITE setMaximumSectionSize) Q_PROPERTY(int maximumSectionSize READ maximumSectionSize WRITE setMaximumSectionSize)
Q_PROPERTY(Qt::Alignment defaultAlignment READ defaultAlignment WRITE setDefaultAlignment) Q_PROPERTY(Qt::Alignment defaultAlignment READ defaultAlignment WRITE setDefaultAlignment)
@ -156,6 +156,7 @@ public:
int defaultSectionSize() const; int defaultSectionSize() const;
void setDefaultSectionSize(int size); void setDefaultSectionSize(int size);
void resetDefaultSectionSize();
int minimumSectionSize() const; int minimumSectionSize() const;
void setMinimumSectionSize(int size); void setMinimumSectionSize(int size);

View File

@ -84,6 +84,7 @@ public:
cascadingResizing(false), cascadingResizing(false),
resizeRecursionBlock(false), resizeRecursionBlock(false),
allowUserMoveOfSection0(true), // will be false for QTreeView and true for QTableView allowUserMoveOfSection0(true), // will be false for QTreeView and true for QTableView
customDefaultSectionSize(false),
stretchSections(0), stretchSections(0),
contentsSections(0), contentsSections(0),
minimumSectionSize(-1), minimumSectionSize(-1),
@ -155,8 +156,7 @@ public:
inline void setDefaultValues(Qt::Orientation o) { inline void setDefaultValues(Qt::Orientation o) {
orientation = o; orientation = o;
defaultSectionSize = (o == Qt::Horizontal ? 100 updateDefaultSectionSizeFromStyle();
: qMax(q_func()->minimumSectionSize(), 30));
defaultAlignment = (o == Qt::Horizontal defaultAlignment = (o == Qt::Horizontal
? Qt::Alignment(Qt::AlignCenter) ? Qt::Alignment(Qt::AlignCenter)
: Qt::AlignLeft|Qt::AlignVCenter); : Qt::AlignLeft|Qt::AlignVCenter);
@ -275,6 +275,7 @@ public:
bool cascadingResizing; bool cascadingResizing;
bool resizeRecursionBlock; bool resizeRecursionBlock;
bool allowUserMoveOfSection0; bool allowUserMoveOfSection0;
bool customDefaultSectionSize;
int stretchSections; int stretchSections;
int contentsSections; int contentsSections;
int defaultSectionSize; int defaultSectionSize;
@ -321,6 +322,7 @@ public:
void removeSectionsFromSectionItems(int start, int end); void removeSectionsFromSectionItems(int start, int end);
void resizeSectionItem(int visualIndex, int oldSize, int newSize); void resizeSectionItem(int visualIndex, int oldSize, int newSize);
void setDefaultSectionSize(int size); void setDefaultSectionSize(int size);
void updateDefaultSectionSizeFromStyle();
void recalcSectionStartPos() const; // not really const void recalcSectionStartPos() const; // not really const
inline int headerLength() const { // for debugging 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: case PM_HeaderGripMargin:
ret = int(QStyleHelper::dpiScaled(4.)); ret = int(QStyleHelper::dpiScaled(4.));
break; break;
case PM_HeaderDefaultSectionSizeHorizontal:
ret = int(QStyleHelper::dpiScaled(100.));
break;
case PM_HeaderDefaultSectionSizeVertical:
ret = int(QStyleHelper::dpiScaled(30.));
break;
case PM_TabBarScrollButtonWidth: case PM_TabBarScrollButtonWidth:
ret = int(QStyleHelper::dpiScaled(16.)); ret = int(QStyleHelper::dpiScaled(16.));
break; 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. \value PM_TreeViewIndentation The indentation of items in a tree view.
This enum value has been introduced in Qt 5.4. 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 \value PM_CustomBase Base value for custom pixel metrics. Custom
values must be greater than this value. values must be greater than this value.

View File

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

View File

@ -176,6 +176,7 @@ private slots:
void moveSectionAndRemove(); void moveSectionAndRemove();
void saveRestore(); void saveRestore();
void defaultSectionSizeTest(); void defaultSectionSizeTest();
void defaultSectionSizeTestStyles();
void defaultAlignment_data(); void defaultAlignment_data();
void defaultAlignment(); void defaultAlignment();
@ -1679,6 +1680,41 @@ void tst_QHeaderView::defaultSectionSizeTest()
QVERIFY(hv->sectionSize(2) == 0); // section is hidden. It should not be resized. 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() void tst_QHeaderView::defaultAlignment_data()
{ {