PDA

View Full Version : App crash when using context menu for change model



doecz
6th November 2012, 19:02
Hi,
I need to change model using context menu of QTreeView. The problem occurs when is closed the context menu, that requested paint event QTreeView, and during drawing is call model->update(), which resets the model and it causes the app crash.

valgrind:


==8920== Invalid read of size 8
==8920== at 0x4380D3: GerberNode::parent() (gerbernode.cpp:59)
==8920== by 0x447F0C: PropertyModel::parent(QModelIndex const&) const (propertymodel.cpp:422)
==8920== by 0x5A914AB: QProxyModel::parent(QModelIndex const&) const (in /usr/lib/libQtGui.so.4.8.3)
==8920== by 0x4495BA: PropertyProxy::parent(QModelIndex const&) const (propertyproxy.cpp:58)
==8920== by 0x5A53191: QTreeView::drawRow(QPainter*, QStyleOptionViewItem const&, QModelIndex const&) const (in /usr/lib/libQtGui.so.4.8.3)
==8920== by 0x5A572EE: QTreeView::drawTree(QPainter*, QRegion const&) const (in /usr/lib/libQtGui.so.4.8.3)
==8920== by 0x5A57AFB: QTreeView::paintEvent(QPaintEvent*) (in /usr/lib/libQtGui.so.4.8.3)
==8920== by 0x555D7A1: QWidget::event(QEvent*) (in /usr/lib/libQtGui.so.4.8.3)
==8920== by 0x5908425: QFrame::event(QEvent*) (in /usr/lib/libQtGui.so.4.8.3)
==8920== by 0x5A13A4A: QAbstractItemView::viewportEvent(QEvent*) (in /usr/lib/libQtGui.so.4.8.3)
==8920== by 0x5A58210: QTreeView::viewportEvent(QEvent*) (in /usr/lib/libQtGui.so.4.8.3)
==8920== by 0x615E755: QCoreApplicationPrivate::sendThroughObjectEventFil ters(QObject*, QEvent*) (in /usr/lib/libQtCore.so.4.8.3)
==8920== Address 0x15a3cd80 is 16 bytes inside a block of size 24 free'd
==8920== at 0x4C2A86C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8920== by 0x4393E3: void qDeleteAll<QList<GerberNode*>::const_iterator>(QList<GerberNode*>::const_iterator, QList<GerberNode*>::const_iterator) (qalgorithms.h:322)
==8920== by 0x438D37: void qDeleteAll<QList<GerberNode*> >(QList<GerberNode*> const&) (qalgorithms.h:330)
==8920== by 0x4385C7: GerberNode::clear() (gerbernode.cpp:109)
==8920== by 0x438541: GerberNode::clear() (gerbernode.cpp:107)
==8920== by 0x444C71: PropertyModelPrivate::updateModel() (propertymodel.cpp:46)
==8920== by 0x44681B: PropertyModel::update() (propertymodel.cpp:251)
==8920== by 0x41829D: MainWindow::on_treeProperty_customContextMenuReque sted(QPoint const&) (mainwindow.cpp:433)
==8920== by 0x44D401: MainWindow::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (moc_mainwindow.cpp:96)
==8920== by 0x44D5A7: MainWindow::qt_metacall(QMetaObject::Call, int, void**) (moc_mainwindow.cpp:144)
==8920== by 0x6173C92: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib/libQtCore.so.4.8.3)
==8920== by 0x5550921: QWidget::customContextMenuRequested(QPoint const&) (in /usr/lib/libQtGui.so.4.8.3)
==8920==


mainwindow.cpp


void MainWindow::on_treeProperty_customContextMenuReque sted(const QPoint &aPos)
{
if (iEditStatus->getIndex().isValid()) {
QModelIndex index = iEditStatus->getIndex();
QModelIndex indexModel = iModelGerber->index(index.row(), index.column(), index.parent());
GerbDCode dcode = qVariantValue<GerbDCode>(index.data(Qt::EditRole));

QAction * action = iMenuModifier->exec(ui->treeProperty->mapToGlobal(aPos));

if (action == ui->actionAddModifier) {
double value = dcode.param.at(0).toDouble()/4;
dcode.param.append(value);
iModelGerber->setData(indexModel, QVariant(QMetaType::type("GerbDCode"), &dcode), GerbFormat::ROLE_UNDO);
iModelProperty->update();
ui->treeProperty->expandAll();
}
else if (action == ui->actionRemoveModifier) {
dcode.param.removeLast();
iModelGerber->setData(indexModel, QVariant(QMetaType::type("GerbDCode"), &dcode), GerbFormat::ROLE_UNDO);
iModelProperty->update(); //PropertyModel class
ui->treeProperty->expandAll();
}
}
}


propertymodel.cpp


void PropertyModel::update()
{
Q_D(PropertyModel);
beginResetModel();
d->updateModel();
endResetModel();
}


Any help is appreciated.

pkj
8th November 2012, 08:10
It is tough to tell exactly from the code, but looks like the Gerber::Node::parent() is crashing. Go through the function as to why it is not able to reset. You can verify your model from ModelTest (http://qt-project.org/wiki/Model_Test) which qt provides. Often for complicated tree models, it is good to have.

doecz
8th November 2012, 20:42
Thanks for response. I finally solved the problem by replacing the update() as methods removeRow() and insertRow().