diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 9175a2f4bd..9e1d8d60ed 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -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); diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h index 4376db306f..0f1afae373 100644 --- a/src/widgets/itemviews/qtreeview_p.h +++ b/src/widgets/itemviews/qtreeview_p.h @@ -23,6 +23,8 @@ #include #endif +#include + 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 modelConnections; + std::array headerConnections; + QMetaObject::Connection sortHeaderConnection; }; QT_END_NAMESPACE