QTreeView: Make sure QHeaderView is notified on layoutChanged()

QHeaderViewPrivate::_q_layoutChanged() was not called when used in a
QTreeView because it was explicitly disconnected in setModel().
The disconnect was added sometime prio to Qt 4.3, but there the signal
was connected to the doItemsLayout() slot. This was correct since
QTreeView::doItemsLayout() is calling header->doItemsLayout().
In Qt 4.3.0 _q_layoutChanged() was introduced and the disconnect was
adjusted. But since _q_layoutChanged() is doing much more than
doItemsLayout() (e.g. restoring hidden sections), functionality was
lost. The problem was already observed for Qt 4.6 (QTBUG-18196) but
only partially fixed.

Task-number: QTBUG-41124
Task-number: QTBUG-54610
Change-Id: Id13a9930d0163812e12a0287016bab9c3aa02068
Reviewed-by: Thorbjørn Lund Martsum <tmartsum@gmail.com>
This commit is contained in:
Christian Ehrlicher 2017-11-17 20:57:00 +01:00
parent 9fbd9e066e
commit 93dabeba9d
2 changed files with 24 additions and 3 deletions

View File

@ -237,9 +237,6 @@ void QTreeView::setModel(QAbstractItemModel *model)
// QAbstractItemView connects to a private slot
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
// do header layout after the tree
disconnect(d->model, SIGNAL(layoutChanged()),
d->header, SLOT(_q_layoutChanged()));
// QTreeView has a public slot for this
connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(rowsRemoved(QModelIndex,int,int)));

View File

@ -313,6 +313,17 @@ public:
endRemoveColumns();
}
void removeAddLastColumnLayoutChanged() // for taskQTBUG_41124
{
// make sure QHeaderView::_q_layoutChanged() is called
emit layoutAboutToBeChanged();
--cols;
emit layoutChanged();
emit layoutAboutToBeChanged();
++cols;
emit layoutChanged();
}
void removeAllColumns()
{
beginRemoveColumns(QModelIndex(), 0, cols - 1);
@ -1306,6 +1317,19 @@ void tst_QTreeView::columnHidden()
for (int c = 0; c < model.columnCount(); ++c)
QCOMPARE(view.isColumnHidden(c), true);
view.update();
// QTBUG_41124:
// QHeaderViewPrivate::_q_layoutChanged was not called because it was
// disconnected in QTreeView::setModel(). _q_layoutChanged restores
// the hidden sections which is tested here
view.setColumnHidden(model.cols - 1, true);
model.removeAddLastColumnLayoutChanged();
// we removed the last column and added a new one
// (with layoutToBeChanged/layoutChanged() for both) so column
// 1 is a new column and therefore must not be hidden when
// _q_layoutChanged() is called and is doing the right stuff
QCOMPARE(view.isColumnHidden(model.cols - 1), false);
}
void tst_QTreeView::rowHidden()