Widgets/Itemviews: use pmf-style connect in QTableView
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: Ifd6a55080a803b3aba2e35b9679a5194ff3f633c Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
This commit is contained in:
parent
2203dec57b
commit
3e144bdc74
@ -595,10 +595,26 @@ void QTableViewPrivate::init()
|
|||||||
#if QT_CONFIG(abstractbutton)
|
#if QT_CONFIG(abstractbutton)
|
||||||
cornerWidget = new QTableCornerButton(q);
|
cornerWidget = new QTableCornerButton(q);
|
||||||
cornerWidget->setFocusPolicy(Qt::NoFocus);
|
cornerWidget->setFocusPolicy(Qt::NoFocus);
|
||||||
QObject::connect(cornerWidget, SIGNAL(clicked()), q, SLOT(selectAll()));
|
cornerWidgetConnection = QObject::connect(
|
||||||
|
cornerWidget, &QTableCornerButton::clicked,
|
||||||
|
q, &QTableView::reset);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QTableViewPrivate::clearConnections()
|
||||||
|
{
|
||||||
|
for (const QMetaObject::Connection &connection : modelConnections)
|
||||||
|
QObject::disconnect(connection);
|
||||||
|
for (const QMetaObject::Connection &connection : verHeaderConnections)
|
||||||
|
QObject::disconnect(connection);
|
||||||
|
for (const QMetaObject::Connection &connection : horHeaderConnections)
|
||||||
|
QObject::disconnect(connection);
|
||||||
|
for (const QMetaObject::Connection &connection : dynHorHeaderConnections)
|
||||||
|
QObject::disconnect(connection);
|
||||||
|
QObject::disconnect(selectionmodelConnection);
|
||||||
|
QObject::disconnect(cornerWidgetConnection);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\internal
|
\internal
|
||||||
Trims away indices that are hidden in the treeview due to hidden horizontal or vertical sections.
|
Trims away indices that are hidden in the treeview due to hidden horizontal or vertical sections.
|
||||||
@ -1222,6 +1238,8 @@ QTableView::QTableView(QTableViewPrivate &dd, QWidget *parent)
|
|||||||
*/
|
*/
|
||||||
QTableView::~QTableView()
|
QTableView::~QTableView()
|
||||||
{
|
{
|
||||||
|
Q_D(QTableView);
|
||||||
|
d->clearConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1245,28 +1263,23 @@ void QTableView::setModel(QAbstractItemModel *model)
|
|||||||
return;
|
return;
|
||||||
//let's disconnect from the old model
|
//let's disconnect from the old model
|
||||||
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
|
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
|
||||||
disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
for (const QMetaObject::Connection &connection : d->modelConnections)
|
||||||
this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));
|
disconnect(connection);
|
||||||
disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
|
|
||||||
this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));
|
|
||||||
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
|
|
||||||
this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));
|
|
||||||
disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
|
|
||||||
this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));
|
|
||||||
}
|
}
|
||||||
if (d->selectionModel) { // support row editing
|
if (d->selectionModel) { // support row editing
|
||||||
disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
|
disconnect(d->selectionmodelConnection);
|
||||||
d->model, SLOT(submit()));
|
|
||||||
}
|
}
|
||||||
if (model) { //and connect to the new one
|
if (model) { //and connect to the new one
|
||||||
connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
d->modelConnections = {
|
||||||
this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));
|
QObjectPrivate::connect(model, &QAbstractItemModel::rowsInserted,
|
||||||
connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
|
d, &QTableViewPrivate::_q_updateSpanInsertedRows),
|
||||||
this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));
|
QObjectPrivate::connect(model, &QAbstractItemModel::columnsInserted,
|
||||||
connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
|
d, &QTableViewPrivate::_q_updateSpanInsertedColumns),
|
||||||
this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));
|
QObjectPrivate::connect(model, &QAbstractItemModel::rowsRemoved,
|
||||||
connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
|
d, &QTableViewPrivate::_q_updateSpanRemovedRows),
|
||||||
this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));
|
QObjectPrivate::connect(model, &QAbstractItemModel::columnsRemoved,
|
||||||
|
d, &QTableViewPrivate::_q_updateSpanRemovedColumns)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
d->verticalHeader->setModel(model);
|
d->verticalHeader->setModel(model);
|
||||||
d->horizontalHeader->setModel(model);
|
d->horizontalHeader->setModel(model);
|
||||||
@ -1308,8 +1321,7 @@ void QTableView::setSelectionModel(QItemSelectionModel *selectionModel)
|
|||||||
Q_ASSERT(selectionModel);
|
Q_ASSERT(selectionModel);
|
||||||
if (d->selectionModel) {
|
if (d->selectionModel) {
|
||||||
// support row editing
|
// support row editing
|
||||||
disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
|
disconnect(d->selectionmodelConnection);
|
||||||
d->model, SLOT(submit()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d->verticalHeader->setSelectionModel(selectionModel);
|
d->verticalHeader->setSelectionModel(selectionModel);
|
||||||
@ -1318,8 +1330,9 @@ void QTableView::setSelectionModel(QItemSelectionModel *selectionModel)
|
|||||||
|
|
||||||
if (d->selectionModel) {
|
if (d->selectionModel) {
|
||||||
// support row editing
|
// support row editing
|
||||||
connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
|
d->selectionmodelConnection =
|
||||||
d->model, SLOT(submit()));
|
connect(d->selectionModel, &QItemSelectionModel::currentRowChanged,
|
||||||
|
d->model, &QAbstractItemModel::submit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1356,6 +1369,8 @@ void QTableView::setHorizontalHeader(QHeaderView *header)
|
|||||||
|
|
||||||
if (!header || header == d->horizontalHeader)
|
if (!header || header == d->horizontalHeader)
|
||||||
return;
|
return;
|
||||||
|
for (const QMetaObject::Connection &connection : d->horHeaderConnections)
|
||||||
|
disconnect(connection);
|
||||||
if (d->horizontalHeader && d->horizontalHeader->parent() == this)
|
if (d->horizontalHeader && d->horizontalHeader->parent() == this)
|
||||||
delete d->horizontalHeader;
|
delete d->horizontalHeader;
|
||||||
d->horizontalHeader = header;
|
d->horizontalHeader = header;
|
||||||
@ -1367,18 +1382,18 @@ void QTableView::setHorizontalHeader(QHeaderView *header)
|
|||||||
d->horizontalHeader->setSelectionModel(d->selectionModel);
|
d->horizontalHeader->setSelectionModel(d->selectionModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(d->horizontalHeader,SIGNAL(sectionResized(int,int,int)),
|
d->horHeaderConnections = {
|
||||||
this, SLOT(columnResized(int,int,int)));
|
connect(d->horizontalHeader,&QHeaderView::sectionResized,
|
||||||
connect(d->horizontalHeader, SIGNAL(sectionMoved(int,int,int)),
|
this, &QTableView::columnResized),
|
||||||
this, SLOT(columnMoved(int,int,int)));
|
connect(d->horizontalHeader, &QHeaderView::sectionMoved,
|
||||||
connect(d->horizontalHeader, SIGNAL(sectionCountChanged(int,int)),
|
this, &QTableView::columnMoved),
|
||||||
this, SLOT(columnCountChanged(int,int)));
|
connect(d->horizontalHeader, &QHeaderView::sectionCountChanged,
|
||||||
connect(d->horizontalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int)));
|
this, &QTableView::columnCountChanged),
|
||||||
connect(d->horizontalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectColumn(int)));
|
connect(d->horizontalHeader, &QHeaderView::sectionHandleDoubleClicked,
|
||||||
connect(d->horizontalHeader, SIGNAL(sectionHandleDoubleClicked(int)),
|
this, &QTableView::resizeColumnToContents),
|
||||||
this, SLOT(resizeColumnToContents(int)));
|
connect(d->horizontalHeader, &QHeaderView::geometriesChanged,
|
||||||
connect(d->horizontalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));
|
this, &QTableView::updateGeometries),
|
||||||
|
};
|
||||||
//update the sorting enabled states on the new header
|
//update the sorting enabled states on the new header
|
||||||
setSortingEnabled(d->sortingEnabled);
|
setSortingEnabled(d->sortingEnabled);
|
||||||
}
|
}
|
||||||
@ -1394,6 +1409,8 @@ void QTableView::setVerticalHeader(QHeaderView *header)
|
|||||||
|
|
||||||
if (!header || header == d->verticalHeader)
|
if (!header || header == d->verticalHeader)
|
||||||
return;
|
return;
|
||||||
|
for (const QMetaObject::Connection &connection : d->verHeaderConnections)
|
||||||
|
disconnect(connection);
|
||||||
if (d->verticalHeader && d->verticalHeader->parent() == this)
|
if (d->verticalHeader && d->verticalHeader->parent() == this)
|
||||||
delete d->verticalHeader;
|
delete d->verticalHeader;
|
||||||
d->verticalHeader = header;
|
d->verticalHeader = header;
|
||||||
@ -1405,17 +1422,22 @@ void QTableView::setVerticalHeader(QHeaderView *header)
|
|||||||
d->verticalHeader->setSelectionModel(d->selectionModel);
|
d->verticalHeader->setSelectionModel(d->selectionModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(d->verticalHeader, SIGNAL(sectionResized(int,int,int)),
|
d->verHeaderConnections = {
|
||||||
this, SLOT(rowResized(int,int,int)));
|
connect(d->verticalHeader, &QHeaderView::sectionResized,
|
||||||
connect(d->verticalHeader, SIGNAL(sectionMoved(int,int,int)),
|
this, &QTableView::rowResized),
|
||||||
this, SLOT(rowMoved(int,int,int)));
|
connect(d->verticalHeader, &QHeaderView::sectionMoved,
|
||||||
connect(d->verticalHeader, SIGNAL(sectionCountChanged(int,int)),
|
this, &QTableView::rowMoved),
|
||||||
this, SLOT(rowCountChanged(int,int)));
|
connect(d->verticalHeader, &QHeaderView::sectionCountChanged,
|
||||||
connect(d->verticalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectRow(int)));
|
this, &QTableView::rowCountChanged),
|
||||||
connect(d->verticalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectRow(int)));
|
connect(d->verticalHeader, &QHeaderView::sectionPressed,
|
||||||
connect(d->verticalHeader, SIGNAL(sectionHandleDoubleClicked(int)),
|
this, &QTableView::selectRow),
|
||||||
this, SLOT(resizeRowToContents(int)));
|
connect(d->verticalHeader, &QHeaderView::sectionHandleDoubleClicked,
|
||||||
connect(d->verticalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));
|
this, &QTableView::resizeRowToContents),
|
||||||
|
connect(d->verticalHeader, &QHeaderView::geometriesChanged,
|
||||||
|
this, &QTableView::updateGeometries),
|
||||||
|
QObjectPrivate::connect(d->verticalHeader, &QHeaderView::sectionEntered,
|
||||||
|
d, &QTableViewPrivate::_q_selectRow)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2707,24 +2729,25 @@ void QTableView::setSortingEnabled(bool enable)
|
|||||||
{
|
{
|
||||||
Q_D(QTableView);
|
Q_D(QTableView);
|
||||||
horizontalHeader()->setSortIndicatorShown(enable);
|
horizontalHeader()->setSortIndicatorShown(enable);
|
||||||
|
for (const QMetaObject::Connection &connection : d->dynHorHeaderConnections)
|
||||||
|
disconnect(connection);
|
||||||
|
d->dynHorHeaderConnections.clear();
|
||||||
if (enable) {
|
if (enable) {
|
||||||
disconnect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
|
|
||||||
this, SLOT(_q_selectColumn(int)));
|
|
||||||
disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)),
|
|
||||||
this, SLOT(selectColumn(int)));
|
|
||||||
//sortByColumn has to be called before we connect or set the sortingEnabled flag
|
//sortByColumn has to be called before we connect or set the sortingEnabled flag
|
||||||
// because otherwise it will not call sort on the model.
|
// because otherwise it will not call sort on the model.
|
||||||
sortByColumn(horizontalHeader()->sortIndicatorSection(),
|
sortByColumn(d->horizontalHeader->sortIndicatorSection(),
|
||||||
horizontalHeader()->sortIndicatorOrder());
|
d->horizontalHeader->sortIndicatorOrder());
|
||||||
connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
|
d->dynHorHeaderConnections = {
|
||||||
this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
|
QObjectPrivate::connect(d->horizontalHeader, &QHeaderView::sortIndicatorChanged,
|
||||||
|
d, &QTableViewPrivate::_q_sortIndicatorChanged)
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
connect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
|
d->dynHorHeaderConnections = {
|
||||||
this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection);
|
connect(d->horizontalHeader, &QHeaderView::sectionPressed,
|
||||||
connect(horizontalHeader(), SIGNAL(sectionPressed(int)),
|
this, &QTableView::selectColumn),
|
||||||
this, SLOT(selectColumn(int)), Qt::UniqueConnection);
|
QObjectPrivate::connect(d->horizontalHeader, &QHeaderView::sectionEntered,
|
||||||
disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
|
d, &QTableViewPrivate::_q_selectColumn)
|
||||||
this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
|
};
|
||||||
}
|
}
|
||||||
d->sortingEnabled = enable;
|
d->sortingEnabled = enable;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include "private/qabstractitemview_p.h"
|
#include "private/qabstractitemview_p.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
QT_REQUIRE_CONFIG(tableview);
|
QT_REQUIRE_CONFIG(tableview);
|
||||||
|
|
||||||
@ -96,7 +98,9 @@ private:
|
|||||||
|
|
||||||
Q_DECLARE_TYPEINFO ( QSpanCollection::Span, Q_RELOCATABLE_TYPE);
|
Q_DECLARE_TYPEINFO ( QSpanCollection::Span, Q_RELOCATABLE_TYPE);
|
||||||
|
|
||||||
|
#if QT_CONFIG(abstractbutton)
|
||||||
|
class QTableCornerButton;
|
||||||
|
#endif
|
||||||
class Q_AUTOTEST_EXPORT QTableViewPrivate : public QAbstractItemViewPrivate
|
class Q_AUTOTEST_EXPORT QTableViewPrivate : public QAbstractItemViewPrivate
|
||||||
{
|
{
|
||||||
Q_DECLARE_PUBLIC(QTableView)
|
Q_DECLARE_PUBLIC(QTableView)
|
||||||
@ -114,6 +118,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void init();
|
void init();
|
||||||
|
void clearConnections();
|
||||||
void trimHiddenSelections(QItemSelectionRange *range) const;
|
void trimHiddenSelections(QItemSelectionRange *range) const;
|
||||||
QRect intersectedRect(const QRect rect, const QModelIndex &topLeft, const QModelIndex &bottomRight) const override;
|
QRect intersectedRect(const QRect rect, const QModelIndex &topLeft, const QModelIndex &bottomRight) const override;
|
||||||
|
|
||||||
@ -159,8 +164,15 @@ public:
|
|||||||
QHeaderView *horizontalHeader;
|
QHeaderView *horizontalHeader;
|
||||||
QHeaderView *verticalHeader;
|
QHeaderView *verticalHeader;
|
||||||
#if QT_CONFIG(abstractbutton)
|
#if QT_CONFIG(abstractbutton)
|
||||||
QWidget *cornerWidget;
|
QTableCornerButton *cornerWidget;
|
||||||
|
QMetaObject::Connection cornerWidgetConnection;
|
||||||
#endif
|
#endif
|
||||||
|
QMetaObject::Connection selectionmodelConnection;
|
||||||
|
std::array<QMetaObject::Connection, 4> modelConnections;
|
||||||
|
std::array<QMetaObject::Connection, 7> verHeaderConnections;
|
||||||
|
std::array<QMetaObject::Connection, 5> horHeaderConnections;
|
||||||
|
std::vector<QMetaObject::Connection> dynHorHeaderConnections;
|
||||||
|
|
||||||
bool sortingEnabled;
|
bool sortingEnabled;
|
||||||
bool geometryRecursionBlock;
|
bool geometryRecursionBlock;
|
||||||
QPoint visualCursor; // (Row,column) cell coordinates to track through span navigation.
|
QPoint visualCursor; // (Row,column) cell coordinates to track through span navigation.
|
||||||
|
Loading…
Reference in New Issue
Block a user