Widgets/Itemviews: use pmf-style connect in QTreeView

Replace all connect() calls with pmf-style connection syntax. This also
means that we have to properly disconnect everything in the ctor to not
trigger an assertion in QtPrivate::assertObjectType().

Task-number: QTBUG-117698
Change-Id: Ic6617b3611a2ce156e9e568c1d07343f649562c4
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
This commit is contained in:
Christian Ehrlicher 2023-09-24 19:40:16 +02:00
parent 3e144bdc74
commit 0bb35ee2f0
2 changed files with 66 additions and 39 deletions

View File

@ -169,6 +169,8 @@ QTreeView::QTreeView(QTreeViewPrivate &dd, QWidget *parent)
*/
QTreeView::~QTreeView()
{
Q_D(QTreeView);
d->clearConnections();
}
/*!
@ -180,18 +182,12 @@ void QTreeView::setModel(QAbstractItemModel *model)
if (model == d->model)
return;
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(rowsRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
for (const QMetaObject::Connection &connection : d->modelConnections)
QObject::disconnect(connection);
}
if (d->selectionModel) { // support row editing
disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
d->model, SLOT(submit()));
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(rowsRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
QObject::disconnect(d->selectionmodelConnection);
}
d->viewItems.clear();
d->expandedIndexes.clear();
@ -201,18 +197,22 @@ void QTreeView::setModel(QAbstractItemModel *model)
d->geometryRecursionBlock = false;
QAbstractItemView::setModel(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)));
connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset()));
if (d->model) {
// QAbstractItemView connects to a private slot
QObjectPrivate::disconnect(d->model, &QAbstractItemModel::rowsRemoved,
d, &QAbstractItemViewPrivate::_q_rowsRemoved);
// do header layout after the tree
QObjectPrivate::disconnect(d->model, &QAbstractItemModel::layoutChanged,
d->header->d_func(), &QAbstractItemViewPrivate::_q_layoutChanged);
d->modelConnections = {
// QTreeView has a public slot for this
QObject::connect(d->model, &QAbstractItemModel::rowsRemoved,
this, &QTreeView::rowsRemoved),
QObjectPrivate::connect(d->model, &QAbstractItemModel::modelAboutToBeReset,
d, &QTreeViewPrivate::_q_modelAboutToBeReset)
};
}
if (d->sortingEnabled)
d->_q_sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
}
@ -236,8 +236,7 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel)
Q_ASSERT(selectionModel);
if (d->selectionModel) {
// support row editing
disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
d->model, SLOT(submit()));
QObject::disconnect(d->selectionmodelConnection);
}
d->header->setSelectionModel(selectionModel);
@ -245,8 +244,9 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel)
if (d->selectionModel) {
// support row editing
connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
d->model, SLOT(submit()));
d->selectionmodelConnection =
connect(d->selectionModel, &QItemSelectionModel::currentRowChanged,
d->model, &QAbstractItemModel::submit);
}
}
@ -286,16 +286,18 @@ void QTreeView::setHeader(QHeaderView *header)
d->header->setSelectionModel(d->selectionModel);
}
connect(d->header, SIGNAL(sectionResized(int,int,int)),
this, SLOT(columnResized(int,int,int)));
connect(d->header, SIGNAL(sectionMoved(int,int,int)),
this, SLOT(columnMoved()));
connect(d->header, SIGNAL(sectionCountChanged(int,int)),
this, SLOT(columnCountChanged(int,int)));
connect(d->header, SIGNAL(sectionHandleDoubleClicked(int)),
this, SLOT(resizeColumnToContents(int)));
connect(d->header, SIGNAL(geometriesChanged()),
this, SLOT(updateGeometries()));
d->headerConnections = {
connect(d->header, &QHeaderView::sectionResized,
this, &QTreeView::columnResized),
connect(d->header, &QHeaderView::sectionMoved,
this, &QTreeView::columnMoved),
connect(d->header, &QHeaderView::sectionCountChanged,
this, &QTreeView::columnCountChanged),
connect(d->header, &QHeaderView::sectionHandleDoubleClicked,
this, &QTreeView::resizeColumnToContents),
connect(d->header, &QHeaderView::geometriesChanged,
this, &QTreeView::updateGeometries)
};
setSortingEnabled(d->sortingEnabled);
d->updateGeometry();
@ -839,11 +841,12 @@ void QTreeView::setSortingEnabled(bool enable)
//sortByColumn has to be called before we connect or set the sortingEnabled flag
// because otherwise it will not call sort on the model.
sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
d->sortHeaderConnection =
QObjectPrivate::connect(header(), &QHeaderView::sortIndicatorChanged,
d, &QTreeViewPrivate::_q_sortIndicatorChanged,
Qt::UniqueConnection);
} else {
disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
QObject::disconnect(d->sortHeaderConnection);
}
d->sortingEnabled = enable;
}
@ -3088,10 +3091,25 @@ void QTreeViewPrivate::initialize()
q->setHeader(header);
#if QT_CONFIG(animation)
animationsEnabled = q->style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, q) > 0;
QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));
animationConnection =
QObjectPrivate::connect(&animatedOperation, &QVariantAnimation::finished,
this, &QTreeViewPrivate::_q_endAnimatedOperation);
#endif // animation
}
void QTreeViewPrivate::clearConnections()
{
for (const QMetaObject::Connection &connection : modelConnections)
QObject::disconnect(connection);
for (const QMetaObject::Connection &connection : headerConnections)
QObject::disconnect(connection);
QObject::disconnect(selectionmodelConnection);
QObject::disconnect(sortHeaderConnection);
#if QT_CONFIG(animation)
QObject::disconnect(animationConnection);
#endif
}
void QTreeViewPrivate::expand(int item, bool emitSignal)
{
Q_Q(QTreeView);

View File

@ -23,6 +23,8 @@
#include <QtCore/qvariantanimation.h>
#endif
#include <array>
QT_REQUIRE_CONFIG(treeview);
QT_BEGIN_NAMESPACE
@ -62,6 +64,7 @@ public:
~QTreeViewPrivate() {}
void initialize();
void clearConnections();
int logicalIndexForTree() const;
inline bool isTreePosition(int logicalIndex) const
{
@ -254,6 +257,12 @@ public:
// tree position
int treePosition;
QMetaObject::Connection animationConnection;
QMetaObject::Connection selectionmodelConnection;
std::array<QMetaObject::Connection, 2> modelConnections;
std::array<QMetaObject::Connection, 5> headerConnections;
QMetaObject::Connection sortHeaderConnection;
};
QT_END_NAMESPACE