2016-10-29 6 views
1

私はカスタムQAbstractTableModelと最初のモデルの軸を反転させるプロキシモデルを持っています。テーブルがあれば、モデルを切り替えるだけです。グラフのプロキシモデルに切り替えると、QHXYModelMapperに行を割り当てるポイントでクラッシュします。私は何をねじ込みましたか?My Qt QAbstractProxyModelがChartViewでクラッシュしますが、TableViewではクラッシュしませんか?

これはテーブルモデルである:

#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(); 
} 

EDIT

詳細...

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:

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

ドキュメントのデフォルト値がすることを意味しているように見える:だから

を修正するようにように、私が今持っている修正は、手動でQHXYModelMapper::setColumnCount()を呼び出すことです明示的に設定しない場合は、モデルの列の合計数を使用します。

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

+0

あなたは '(もし!役割= Qtの:: DisplayRole)を書きたかった'どこ現在、 ''(!役割== Qtの:: DisplayRole)場合がありますか? –

+0

はい、ありがとう!それはこのバグの原因には見えませんが、確かに他の人たちが道を塞いでしまうでしょう。 – Yosemite

+0

データメソッドが無効なインデックスで呼び出されるため、ベクトルのインデックス演算子でアクセス違反が発生するため、問題はプロキシのインデックスマッピングで発生する可能性が高くなります。 バックトレースは、プロキシ基底クラスの 'data()'実装がソースモデルの 'data()'メソッドを呼び出したことを明確に示しています。つまり、プロキシの 'mapToSource()'が最初に呼び出されます。おそらく、無効なインデックスを返します。 –

答えて

0

Qtフォーラムで少し話しましたが、これはバグのようです。HXYModelMappercolumnCountプロパティのデフォルト値は実際には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

関連する問題