Russian Qt Forum

Qt => Model-View (MV) => Тема начата: maks1596 от Июнь 03, 2018, 13:51



Название: QTableView не обновляется при обновлении модели
Отправлено: maks1596 от Июнь 03, 2018, 13:51
После установки новых данных в модели QTableView (а точнее его прямой наследник) не обновляется. При отладке установил, что метод data в модели вообще не вызывается.

Model.h
Код
C++ (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.cpp
Код
C++ (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.h
Код
C++ (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. По каёмочки от таблицы видно, что таблица там действительно есть, только абсолютно пустая.


Название: Re: QTableView не обновляется при обновлении модели
Отправлено: __Heaven__ от Июнь 04, 2018, 09:05
Можно попробовать layoutChanged (http://doc.qt.io/qt-5/qabstractitemmodel.html#layoutChanged)


Название: Re: QTableView не обновляется при обновлении модели
Отправлено: __Heaven__ от Июнь 04, 2018, 09:06
dataChanged третьим аргументом принимает роли. Быть может явное указание поможет


Название: Re: QTableView не обновляется при обновлении модели
Отправлено: maks1596 от Июнь 04, 2018, 10:06
Цитировать
dataChanged третьим аргументом принимает роли. Быть может явное указание поможет

Неа, не сработало.
Сработал следующий кусок кода:
Код
C++ (Qt)
void CorrelationsModel::setGroupsCorrelations(const QList<GroupCorrelations> &groupsCorrelations) {
   beginResetModel();
   m_groupsCorrelations = groupsCorrelations;
   endResetModel();
}