Widgets/Itemviews: use pmf-style connect in QHeaderView

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: Ia0745dc10a917f3af4b448b3156d66bdb5d6ce64
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
bb10
Christian Ehrlicher 2023-09-24 19:38:32 +02:00
parent 39d486171b
commit f8fc93fdef
2 changed files with 38 additions and 60 deletions

View File

@ -295,6 +295,8 @@ QHeaderView::QHeaderView(QHeaderViewPrivate &dd,
QHeaderView::~QHeaderView()
{
Q_D(QHeaderView);
d->disconnectModel();
}
/*!
@ -322,68 +324,35 @@ void QHeaderView::setModel(QAbstractItemModel *model)
return;
Q_D(QHeaderView);
d->layoutChangePersistentSections.clear();
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
if (d->orientation == Qt::Horizontal) {
QObject::disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
this, SLOT(sectionsInserted(QModelIndex,int,int)));
QObject::disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
QObject::disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
QObject::disconnect(d->model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT(_q_sectionsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
QObject::disconnect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT(_q_sectionsMoved(QModelIndex,int,int,QModelIndex,int)));
} else {
QObject::disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(sectionsInserted(QModelIndex,int,int)));
QObject::disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
QObject::disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
QObject::disconnect(d->model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT(_q_sectionsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
QObject::disconnect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT(_q_sectionsMoved(QModelIndex,int,int,QModelIndex,int)));
}
QObject::disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
this, SLOT(headerDataChanged(Qt::Orientation,int,int)));
QObject::disconnect(d->model, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
this, SLOT(_q_sectionsAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
QObject::disconnect(d->model, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
this, SLOT(_q_sectionsChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
}
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel())
d->disconnectModel();
if (model && model != QAbstractItemModelPrivate::staticEmptyModel()) {
if (d->orientation == Qt::Horizontal) {
QObject::connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
this, SLOT(sectionsInserted(QModelIndex,int,int)));
QObject::connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
QObject::connect(model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT(_q_sectionsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
QObject::connect(model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT(_q_sectionsMoved(QModelIndex,int,int,QModelIndex,int)));
} else {
QObject::connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(sectionsInserted(QModelIndex,int,int)));
QObject::connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
QObject::connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
QObject::connect(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT(_q_sectionsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
QObject::connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
this, SLOT(_q_sectionsMoved(QModelIndex,int,int,QModelIndex,int)));
}
QObject::connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
this, SLOT(headerDataChanged(Qt::Orientation,int,int)));
QObject::connect(model, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
this, SLOT(_q_sectionsAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
QObject::connect(model, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
this, SLOT(_q_sectionsChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
const bool hor = d->orientation == Qt::Horizontal;
d->modelConnections = {
QObject::connect(model, hor ? &QAbstractItemModel::columnsInserted
: &QAbstractItemModel::rowsInserted,
this, &QHeaderView::sectionsInserted),
QObject::connect(model, hor ? &QAbstractItemModel::columnsAboutToBeRemoved
: &QAbstractItemModel::rowsAboutToBeRemoved,
this, &QHeaderView::sectionsAboutToBeRemoved),
QObjectPrivate::connect(model, hor ? &QAbstractItemModel::columnsRemoved
: &QAbstractItemModel::rowsRemoved,
d, &QHeaderViewPrivate::_q_sectionsRemoved),
QObjectPrivate::connect(model, hor ? &QAbstractItemModel::columnsAboutToBeMoved
: &QAbstractItemModel::rowsAboutToBeMoved,
d, &QHeaderViewPrivate::_q_sectionsAboutToBeMoved),
QObjectPrivate::connect(model, hor ? &QAbstractItemModel::columnsMoved
: &QAbstractItemModel::columnsMoved,
d, &QHeaderViewPrivate::_q_sectionsMoved),
QObject::connect(model, &QAbstractItemModel::headerDataChanged,
this, &QHeaderView::headerDataChanged),
QObjectPrivate::connect(model, &QAbstractItemModel::layoutAboutToBeChanged,
d, &QHeaderViewPrivate::_q_sectionsAboutToBeChanged),
QObjectPrivate::connect(model, &QAbstractItemModel::layoutChanged,
d, &QHeaderViewPrivate::_q_sectionsChanged)
};
}
d->state = QHeaderViewPrivate::NoClear;

View File

@ -25,6 +25,8 @@
#include "QtWidgets/qlabel.h"
#endif
#include <array>
QT_REQUIRE_CONFIG(itemviews);
QT_BEGIN_NAMESPACE
@ -213,6 +215,12 @@ public:
}
}
inline void disconnectModel()
{
for (const QMetaObject::Connection &connection : modelConnections)
QObject::disconnect(connection);
}
void clear();
void flipSortIndicator(int section);
Qt::SortOrder defaultSortOrderForSection(int section) const;
@ -305,6 +313,7 @@ public:
SectionItem section;
};
QList<LayoutChangeItem> layoutChangePersistentSections;
std::array<QMetaObject::Connection, 8> modelConnections;
void createSectionItems(int start, int end, int sectionSize, QHeaderView::ResizeMode mode);
void removeSectionsFromSectionItems(int start, int end);