我的Qt QAbstractProxyModel崩溃与图表视图,但不与表视图
My Qt QAbstractProxyModel crashes with ChartView but not with 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();
}
编辑
Some more info…
查看调试器,似乎在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:修复
所以,我现在的修复是手动调用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
在Qt论坛上讨论了一下,这似乎是一个错误,其中HXYModelMapper
columnCount
属性的默认值实际上并没有从模型中检索适当的columnCount
。解决方法是自己调用setColumnCount
并将其设置为模型的columnCount
。
mapper->setModel(m);
mapper->setSeries(series);
mapper->setColumnCount(m->columnCount());
mapper->setXRow(row);
mapper->setYRow(row);
Bug报告:https://bugreports.qt.io/browse/QTBUG-57342
相关文章:
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- Qt - QVector 和模型视图 - 从列表视图获取自定义类的最佳方法是什么?
- 控制带有信号/插槽的Qt QML滑动视图
- 透视视图的任何解决方案 openGL qt.
- Qt 如何使用鼠标移动事件移动视图
- 当用户在键盘上按住 CTRL 键时,如何在树视图中的 Qt 中实现多选?
- QT Filesystembrowser:如何更改根目录和更新视图
- 将树视图链接到表视图?[QT]
- Qt:将 c++ 中的列表连接到 QML 中的列表视图
- 如何在按下按钮时在Qt表格视图中自动选择下一行?
- Qt C++ - 在一个视图中显示来自多个SQLite表的数据
- 在QT视图中显示位图数据
- Qt中数据类(模型)和视图/控制器类之间的数据通信的正确方式是什么
- Qt在QtWebEngine视图中显示QImage或像素映射(从C++到HTML)
- Qt- 设置来自表视图的输入的验证器
- QT MVC 模式未更新视图 - 特定的 SimpleTreeModel 示例
- 无法在 QML 列表视图中调用 Qt c++ 方法
- 用鼠标中键按下qt图表移动视图
- 关于在模型/视图Qt文档中排序的描述可能是错误的
- 如何在Qt小工具项目中更新图形视图(Qt Creator)