После установки новых данных в модели QTableView (а точнее его прямой наследник) не обновляется. При отладке установил, что метод data в модели вообще не вызывается.
Model.hC++ (Qt)
#pragma once
#include <QAbstractTableModel>
#include "Entities/Statistics/GroupCorrelations/GroupCorrelations.h"
class CorrelationsModel : public QAbstractTableModel {
Q_OBJECT
public:
explicit CorrelationsModel(QObject *parent = nullptr);
// :: QAbstractTableModel ::
// :: Header ::
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
// :: Basic functionality ::
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
// :: Accessors ::
const QList<GroupCorrelations> &getGroupsCorrelations() const;
void setGroupsCorrelations(const QList<GroupCorrelations> &groupsCorrelations);
private:
void checkRowCount(const QList<GroupCorrelations> newGroupsCorrelations);
void checkColumnCount(const QList<GroupCorrelations> newGroupsCorrelations);
int rowCount(const QList<GroupCorrelations> groupsCorrelations) const;
int columnCount(const QList<GroupCorrelations> groupsCorrelations) const;
void emitAllDataChanged();
QList<GroupCorrelations> m_groupsCorrelations;
};
Model.cppC++ (Qt)
#include "CorrelationsModel.h"
// :: Lifecycle ::
CorrelationsModel::CorrelationsModel(QObject *parent)
: QAbstractTableModel(parent)
{ }
// :: QAbstractTableModel ::
QVariant CorrelationsModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (role == Qt::DisplayRole) {
if (orientation == Qt::Vertical) {
if (section < rowCount()) {
return getGroupsCorrelations()
.first()
.getCorrelationValues()
.at(section)
.getName();
}
} else {
if (section < columnCount()) {
return getGroupsCorrelations()
.at(section)
.getGroupName();
}
}
}
return section;
}
int CorrelationsModel::rowCount(const QModelIndex &) const {
return rowCount(getGroupsCorrelations());
}
int CorrelationsModel::columnCount(const QModelIndex &) const {
return columnCount(getGroupsCorrelations());
}
QVariant CorrelationsModel::data(const QModelIndex &index, int role) const {
if (!index.isValid() || role != Qt::DisplayRole) {
return QVariant();
}
return getGroupsCorrelations()
.at(index.column())
.getCorrelationValues()
.at(index.row())
.getValue();
}
// :: Public accessors ::
const QList<GroupCorrelations> &CorrelationsModel::getGroupsCorrelations() const {
return m_groupsCorrelations;
}
void CorrelationsModel::setGroupsCorrelations(const QList<GroupCorrelations> &groupsCorrelations) {
checkRowCount(groupsCorrelations);
checkColumnCount(groupsCorrelations);
m_groupsCorrelations = groupsCorrelations;
emitAllDataChanged();
}
// :: Private methods ::
inline
void CorrelationsModel::checkRowCount(const QList<GroupCorrelations> newGroupsCorrelations) {
int oldRowCount = rowCount();
int newRowCount = rowCount(newGroupsCorrelations);
if (oldRowCount < newRowCount) {
beginInsertRows(QModelIndex(), oldRowCount, newRowCount - 1);
endInsertRows();
} else if (oldRowCount > newRowCount) {
beginRemoveRows(QModelIndex(), newRowCount, oldRowCount - 1);
endRemoveRows();
}
}
inline
void CorrelationsModel::checkColumnCount(const QList<GroupCorrelations> newGroupsCorrelations) {
int oldColumnCount = columnCount();
int newColumnCount = columnCount(newGroupsCorrelations);
if (oldColumnCount < newColumnCount) {
beginInsertColumns(QModelIndex(), oldColumnCount, newColumnCount - 1);
endInsertColumns();
} else if (oldColumnCount > newColumnCount) {
beginRemoveColumns(QModelIndex(), newColumnCount, oldColumnCount - 1);
endRemoveColumns();
}
}
inline
int CorrelationsModel::rowCount(const QList<GroupCorrelations> groupsCorrelations) const {
if (!groupsCorrelations.isEmpty()) {
// Корреляции для всех групп одинаковые и в одинаковом количестве
return groupsCorrelations.first().getCorrelationValues().size();
}
return 0;
}
inline
int CorrelationsModel::columnCount(const QList<GroupCorrelations> groupsCorrelations) const {
return groupsCorrelations.size();
}
inline
void CorrelationsModel::emitAllDataChanged() {
auto topLeft = index(0, 0);
auto bottomRight = index(rowCount() - 1, columnCount() - 1);
emit dataChanged(topLeft, bottomRight);
}
На всякий случай
View.hC++ (Qt)
#pragma once
#include <QTableView>
class CorrelationsForm : public QTableView {
Q_OBJECT
public:
explicit CorrelationsForm(QWidget *parent = nullptr)
: QTableView(parent) {}
signals:
void error(const QString &errorMessage);
};
Где всё собирается
C++ (Qt)
#include "../View/CorrelationsForm.h"
#include "../Model/CorrelationsModel.h"
#include "../Service/CorrelationsService.h"
CorrelationsForm *CorrelationsAssembler::assembly(int testId, int scaleId, QWidget *parent) {
auto view = new CorrelationsForm(parent);
auto model = new CorrelationsModel(view);
auto service = new CorrelationsService(model);
view->setModel(model);
QObject::connect(service, &CorrelationsService::defaultGroupsCorrelationsGot,
model, &CorrelationsModel::setGroupsCorrelations);
QObject::connect(service, &CorrelationsService::error,
view, &CorrelationsForm::error);
QObject::connect(model, &CorrelationsModel::dataChanged,
[view](){
view->resizeColumnsToContents();
view->resizeRowsToContents();
});
service->getDefaultGroupsCorrelations(testId, scaleId);
return view;
}
Заверяю, что данные от сервиса приходят... И не в нулевом количестве :)
В дальнейшем вьюха вставляется QTabWidget. По каёмочки от таблицы видно, что таблица там действительно есть, только абсолютно пустая.
Можно попробовать layoutChanged (http://doc.qt.io/qt-5/qabstractitemmodel.html#layoutChanged)
dataChanged третьим аргументом принимает роли. Быть может явное указание поможет
dataChanged третьим аргументом принимает роли. Быть может явное указание поможет
Неа, не сработало.
Сработал следующий кусок кода:
C++ (Qt)
void CorrelationsModel::setGroupsCorrelations(const QList<GroupCorrelations> &groupsCorrelations) {
beginResetModel();
m_groupsCorrelations = groupsCorrelations;
endResetModel();
}