QListView: fix AdjustToContents (sizeAdjustPolicy)
Unlike an acceptable effect in QTableView + QTreeView setAdjustPolicy(QAbstractScrollArea::AdjustToContents) unfortunately didn't work for QListViews (and QListWidget). This patch corrects QListViews AdjustToContents behavior. [ChangeLog][QtWidgets][QListView] A more correct implementation of QListView::viewportSizeHint has been made. That implies that setting the sizeAdjustPolicy to AdjustToContent on QListView and QListWidget will now cause the view to size after the contents and avoid scrollbars. Pick-to: 6.2 Task-number: QTBUG-58749 Change-Id: I1675115f2348e2fcf0b2c39b451ef337e10eb872 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
0e92ec9728
commit
7502598ef5
@ -3487,7 +3487,47 @@ int QListView::visualIndex(const QModelIndex &index) const
|
||||
*/
|
||||
QSize QListView::viewportSizeHint() const
|
||||
{
|
||||
return QAbstractItemView::viewportSizeHint();
|
||||
Q_D(const QListView);
|
||||
// We don't have a nice simple size hint for invalid or wrapping list views.
|
||||
if (!d->model)
|
||||
return QAbstractItemView::viewportSizeHint();
|
||||
const int rc = d->model->rowCount();
|
||||
if (rc == 0 || isWrapping())
|
||||
return QAbstractItemView::viewportSizeHint();
|
||||
|
||||
QStyleOptionViewItem option;
|
||||
initViewItemOption(&option);
|
||||
|
||||
if (uniformItemSizes()) {
|
||||
QSize sz = d->cachedItemSize;
|
||||
if (!sz.isValid()) {
|
||||
QModelIndex idx = d->model->index(0, d->column, d->root);
|
||||
sz = d->itemSize(option, idx);
|
||||
}
|
||||
sz.setHeight(rc * sz.height());
|
||||
return sz;
|
||||
}
|
||||
|
||||
// Using AdjustToContents with a high number of rows will normally not make sense, so we limit
|
||||
// this to default 1000 (that is btw the default for QHeaderView::resizeContentsPrecision())
|
||||
// (By setting the property _q_resizeContentPrecision the user can however override this).
|
||||
int maximumRows = 1000;
|
||||
const QVariant userOverrideValue = property("_q_resizeContentPrecision");
|
||||
if (userOverrideValue.isValid() && userOverrideValue.toInt() > 0) {
|
||||
maximumRows = userOverrideValue.toInt();
|
||||
}
|
||||
const int rowCount = qMin(rc, maximumRows);
|
||||
|
||||
int h = 0;
|
||||
int w = 0;
|
||||
|
||||
for (int row = 0; row < rowCount; ++row) {
|
||||
QModelIndex idx = d->model->index(row, d->column, d->root);
|
||||
QSize itemSize = d->itemSize(option, idx);
|
||||
h += itemSize.height();
|
||||
w = qMax(w, itemSize.width());
|
||||
}
|
||||
return QSize(w, h);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include <QTimer>
|
||||
#include <QtMath>
|
||||
#include <QProxyStyle>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDialog>
|
||||
|
||||
#include <QtTest/private/qtesthelpers_p.h>
|
||||
#include <QtWidgets/private/qlistview_p.h>
|
||||
@ -166,6 +168,7 @@ private slots:
|
||||
void taskQTBUG_39902_mutualScrollBars();
|
||||
void horizontalScrollingByVerticalWheelEvents();
|
||||
void taskQTBUG_7232_AllowUserToControlSingleStep();
|
||||
void taskQTBUG_58749_adjustToContent();
|
||||
void taskQTBUG_51086_skippingIndexesInSelectedIndexes();
|
||||
void taskQTBUG_47694_indexOutOfBoundBatchLayout();
|
||||
void itemAlignment();
|
||||
@ -2527,6 +2530,45 @@ void tst_QListView::taskQTBUG_7232_AllowUserToControlSingleStep()
|
||||
QCOMPARE(hStep1, lv.horizontalScrollBar()->singleStep());
|
||||
}
|
||||
|
||||
void tst_QListView::taskQTBUG_58749_adjustToContent()
|
||||
{
|
||||
QStandardItemModel model;
|
||||
model.setRowCount(20);
|
||||
model.setColumnCount(1);
|
||||
const QString rowStr = QStringLiteral("Row number txt:");
|
||||
for (int u = 0; u < model.rowCount(); ++u)
|
||||
model.setData(model.index(u, 0), rowStr + QString::number(u));
|
||||
|
||||
QDialog w; // It really should work for QWidget, too, but sometimes an event (like move)
|
||||
// is needed to get the resize triggered.
|
||||
QVBoxLayout *l = new QVBoxLayout(&w);
|
||||
l->setSizeConstraint(QLayout::SetFixedSize);
|
||||
auto *view = new QListView;
|
||||
view->setModel(&model);
|
||||
view->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
|
||||
l->addWidget(view);
|
||||
l->setSizeConstraint(QLayout::SetFixedSize);
|
||||
w.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&w));
|
||||
|
||||
const QString longText = "Here we have a row text that is somewhat longer ...";
|
||||
|
||||
QFontMetrics fm(w.font(), &w);
|
||||
QRect r = fm.boundingRect(model.data(model.index(0, 0)).toString());
|
||||
const int longTextWidth = fm.horizontalAdvance(longText);
|
||||
QVERIFY(w.height() > r.height() * model.rowCount());
|
||||
// We have a width longer than the width for the given index data.
|
||||
QVERIFY(w.width() > r.width());
|
||||
// but ... the width should not have a width matching the much longer text.
|
||||
QVERIFY(w.width() < longTextWidth);
|
||||
|
||||
// use the long text and make sure the width is adjusted.
|
||||
model.setData(model.index(0, 0), longText);
|
||||
QApplication::processEvents();
|
||||
QVERIFY(w.width() > longTextWidth);
|
||||
QVERIFY(view->width() >= longTextWidth);
|
||||
}
|
||||
|
||||
void tst_QListView::taskQTBUG_51086_skippingIndexesInSelectedIndexes()
|
||||
{
|
||||
QStandardItemModel data(10, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user