Мой Qt QAbstractProxyModel падает с ChartView, но не с TableView?

У меня есть пользовательский QAbstractTableModel и модель прокси, которая переворачивает оси первой модели. С таблицей это работает, я просто переключаю модель. Когда я переключаюсь на свою модель прокси для диаграммы, она падает в точке, где я назначаю строки в QHXYModelMapper. Что я облажался?

Это модель стола:

#include "tablemodel.h"
TableModel::TableModel(QObject *parent) :
QAbstractTableModel(parent)
{

}

int TableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_data.count();
}

int TableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
if(m_data.count() < 1)
{
return 0;
}
return m_data[0].count();
}

QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();

if (orientation == Qt::Horizontal) {
if (section % 2 == 0)
return "x";
else
return "y";
} else {
return QString("%1").arg(section + 1);
}
}

QVariant TableModel::data(const QModelIndex &index, int role) const
{
if (!role == Qt::DisplayRole)
{
return QVariant();
}
return m_data[index.row()].at(index.column());
}

bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole) {
m_data[index.row()].replace(index.column(), value.toDouble());
emit dataChanged(index, index);
return true;
}
return false;
}

void TableModel::appendRow(QVector<double> row)
{
emit layoutAboutToBeChanged();
emit beginInsertRows(QModelIndex(), rowCount(), rowCount());

m_data.append(row);

emit endInsertRows();
emit layoutChanged();
}

void TableModel::clear()
{
for(int i = 0; i < m_data.count(); ++i)
{
m_data[i].clear();
}
m_data.clear();
}

Это реализация прокси:

HorizontalProxyModel::HorizontalProxyModel(QObject *parent) : QAbstractProxyModel(parent)
{
}

QModelIndex HorizontalProxyModel::mapToSource(const QModelIndex &proxyIndex) const
{
if (sourceModel()) {
return sourceModel()->index(proxyIndex.column(), proxyIndex.row());
} else {
return QModelIndex();
}
}

QModelIndex HorizontalProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
{
return index(sourceIndex.column(), sourceIndex.row());
}

QModelIndex HorizontalProxyModel::index(int row, int column, const QModelIndex &) const
{
return createIndex(row, column, (void*) 0);
}

QModelIndex HorizontalProxyModel::parent(const QModelIndex &) const
{
return QModelIndex();
}

int HorizontalProxyModel::rowCount(const QModelIndex &) const
{
return sourceModel() ? sourceModel()->columnCount() : 0;
}

int HorizontalProxyModel::columnCount(const QModelIndex &) const
{
return sourceModel() ? sourceModel()->rowCount() : 0;
}

QVariant HorizontalProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (!sourceModel()) { return QVariant(); }
Qt::Orientation new_orientation = orientation == Qt::Horizontal ?
Qt::Vertical : Qt::Horizontal;
return sourceModel() ? sourceModel()->headerData(section, new_orientation, role) : 0;
}

QVariant HorizontalProxyModel::data(const QModelIndex &index) const
{
qDebug() << "h model data";
return sourceModel() ? sourceModel()->data(sourceModel()->index(index.column(), index.row())) : 0;
}

И вот где я назначаю модель:

void MainWindow::plot(QAbstractItemModel* m)
{
QChart* chart = new QChart;

qDebug() << m->rowCount() << " " << m->columnCount();

for(int row = 0; row < m->rowCount(); ++row)
{

QLineSeries *series = new QLineSeries;
QHXYModelMapper* mapper = new QHXYModelMapper;
QString name = "Row " + QString::number(row);

series->setName(name);
mapper->setModel(m);
mapper->setSeries(series);
mapper->setXRow(row);  //crashes here if proxy model
mapper->setYRow(row);

chart->addSeries(series);

}
chart->createDefaultAxes();
QChart* oldChart = chartView->chart();
chartView->setChart(chart);
oldChart->deleteLater();
}

РЕДАКТИРОВАТЬ

Еще немного информации …

Глядя на отладчик, кажется, что индекс, создаваемый в ProxyModel и передаваемый исходной модели, равен -1 / -1 (недействительно). Означает ли строка 9 в этом отладочном выводе, что вызывается базовый класс QAbstractProxyModel :: data () вместо класса из моей производной прокси-модели? Если так, то почему?

1   __pthread_kill

0x7fff91eaff06
2   pthread_kill                                                                                       0x7fff907204ec
3   abort                                                                                              0x7fff876cd6df
4   qt_message_fatal(QtMsgType, QMessageLogContext const&, QString const&)                             0x100ac3e79
5   QMessageLogger::fatal(const char *, ...) const                                                     0x100ac5847
6   qt_assert_x(const char *, const char *, const char *, int)                                         0x100ac0682
7   QList<QVector<double>>::operator[](int) const                               qlist.h            541 0x10000fced
8   TableModel::data(QModelIndex const&, int) const                             tablemodel.cpp     46  0x10000f8f1
9   QAbstractProxyModel::data(QModelIndex const&, int) const                                           0x100c4c28b
10  QtCharts::QXYModelMapperPrivate::valueFromModel(QModelIndex)                                       0x10171dfb3
11  QtCharts::QXYModelMapperPrivate::initializeXYFromModel()                                           0x10171d92f
12  QtCharts::QHXYModelMapper::setYRow(int)                                                            0x101720bf4
13  MainWindow::plot(QAbstractItemModel *)

UDPATE: FIX

Итак, исправление, которое я имею сейчас, это позвонить QHXYModelMapper::setColumnCount() вручную, вот так:

mapper->setModel(m);
mapper->setSeries(series);
mapper->setColumnCount(m->columnCount());
mapper->setXRow(row);
mapper->setYRow(row);

Документы, кажется, подразумевают, что значение по умолчанию будет использовать общее количество столбцов в модели, если я не установлю это явно:

http://doc.qt.io/qt-5/qhxymodelmapper.html#columnCount-prop

1

Решение

Обсудили это на форумах Qt немного, это похоже на ошибку, где значение по умолчанию для HXYModelMapper columnCount свойство на самом деле не получить надлежащее columnCount от модели. Обходной путь должен позвонить setColumnCount себя и установите его на columnCount вашей модели.

mapper->setModel(m);
mapper->setSeries(series);
mapper->setColumnCount(m->columnCount());
mapper->setXRow(row);
mapper->setYRow(row);

Сообщение об ошибке: https://bugreports.qt.io/browse/QTBUG-57342

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]