Russian Qt Forum

Qt => Model-View (MV) => Тема начата: nvek от Декабрь 18, 2017, 16:20



Название: Qt Model/View проблема с битыми индексами [РЕШЕНО]
Отправлено: nvek от Декабрь 18, 2017, 16:20
У меня реализована своя модель, унаследованная от QAbstractItemModel. В QModelIndex я храню не только row и column, но и указатель на объект, к которому относится этот индекс. Если объект удалить, то индекс будет содержать в себе ссылку на удаленный объект.
Приложение падает, когда курсор стоит на элементе.

удаляются элементы внутри beginRemove/endRemove
по стеку вызовов:
    
Код:
.exe!StatTreeCtrl::parent(const QModelIndex & index)Строка 173	C++
  Qt5Cored.dll!QModelIndex::parent()Строка 417 C++
  Qt5Widgetsd.dll!QTreeView::drawRow(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index)Строка 1672 C++
  Qt5Widgetsd.dll!QTreeView::drawTree(QPainter * painter, const QRegion & region)Строка 1511 C++
  Qt5Widgetsd.dll!QTreeView::paintEvent(QPaintEvent * event)Строка 1340 C++
  Qt5Widgetsd.dll!QWidget::event(QEvent * event)Строка 8938 C++
  Qt5Widgetsd.dll!QFrame::event(QEvent * e)Строка 550 C++
  Qt5Widgetsd.dll!QAbstractScrollArea::viewportEvent(QEvent * e)Строка 1213 C++
  Qt5Widgetsd.dll!QAbstractItemView::viewportEvent(QEvent * event)Строка 1748 C++
  Qt5Widgetsd.dll!QTreeView::viewportEvent(QEvent * event)Строка 1321 C++
  Qt5Widgetsd.dll!QAbstractScrollAreaPrivate::viewportEvent(QEvent * event)Строка 111 C++
  Qt5Widgetsd.dll!QAbstractScrollAreaFilter::eventFilter(QObject * o, QEvent * e)Строка 127 C++
  Qt5Cored.dll!QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject * receiver, QEvent * event)Строка 1099 C++
  Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e)Строка 3795 C++
  Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e)Строка 3762 C++
  Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event)Строка 988 C++
  Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event)Строка 234 C++
  Qt5Widgetsd.dll!QWidgetPrivate::sendPaintEvent(const QRegion & toBePainted)Строка 5708 C++
> Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore)Строка 5649 C++
  Qt5Widgetsd.dll!QWidgetBackingStore::doSync()Строка 1395 C++
  Qt5Widgetsd.dll!QWidgetBackingStore::sync()Строка 1180 C++
  Qt5Widgetsd.dll!QWidgetPrivate::syncBackingStore()Строка 1964 C++
  Qt5Widgetsd.dll!QWidget::event(QEvent * event)Строка 9101 C++
  Qt5Widgetsd.dll!QMainWindow::event(QEvent * event)Строка 1544 C++
  Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e)Строка 3799 C++
  Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e)Строка 3762 C++
  Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event)Строка 988 C++
  Qt5Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event)Строка 231 C++
  Qt5Cored.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data)Строка 1649 C++
  Qt5Cored.dll!QEventDispatcherWin32::sendPostedEvents()Строка 1295 C++
  qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents()Строка 82 C++
  Qt5Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp)Строка 445 C++

что происходит
1) курсор на элементе который хочет удалиться
2) элемент удаляется (удаление завернуто в бегин и энд (все как Qt советует)
3) приложение падает

почему так происходит?
ps как вставить спойлер?


Название: Re: Qt Model/View проблема с битыми индексами
Отправлено: ssoft от Декабрь 18, 2017, 17:04
QModelIndex генерируется всегда с помощью метода

Код
C++ (Qt)
QModelIndex QAbstractItemModel::index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const;

на момент, когда модель уже изменена, поэтому он по определению не должен содержать битые указатели или другие данные. Ищите ошибку в реализации данного метода.

PS: Нужно проверить на хранятся ли где QModelIndex, типа current, selected и т.п. При удалении их нужно не забыть почистить.


Название: Re: Qt Model/View проблема с битыми индексами
Отправлено: __Heaven__ от Декабрь 18, 2017, 23:05
ИМХО, пригодится
http://www.prog.org.ru/topic_31100_0.html


Название: Re: Qt Model/View проблема с битыми индексами
Отправлено: nvek от Декабрь 20, 2017, 09:40
__Heaven__, да, я восхищался твоей реализацией. Она мне очень пригодилась в понимании
вот мой индекс
Код:
QModelIndex StatTreeCtrl::index(int row, int column, const QModelIndex & parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();

IStatisticModel::Ptr parentItem;

if (!parent.isValid())
parentItem = rootItem;
else
parentItem = getItem(parent);

IStatisticModel::Ptr childItem = parentItem->children().at(row);

if (childItem)
{
//childItem.duplicate();
return createIndex(row, column, childItem);
}
else
return QModelIndex();

}

собсно TreCtrl это структура это наследник AbstractItemModel
IStatisticModel это структура где хранятся сами элементы
да, возможно где то есть обработчик селект, но элемент то я не выделяю, а навожу на него всеголишь


Название: Re: Qt Model/View проблема с битыми индексами
Отправлено: nvek от Декабрь 20, 2017, 11:12
Я знаю в чем проблема, в методе где обновляется элементы, надо следить, если удаляешь объект, то надо и удалить соответствующий индекс, и если переносишь объект (был std::swap( ) ) то надо и индексы модели свапать beginMoveRow();
интересно еще то, что когда переносится индекс, вместе с ним переносится hover


Название: Re: Qt Model/View проблема с битыми индексами [РЕШЕНО]
Отправлено: nvek от Декабрь 20, 2017, 15:39
Только я вот понять не могу, как происходит или как может происходить ошибка если bebinInsert/endInsert написать отдельно либо до добавления, либо после добавления