Russian Qt Forum
Ноябрь 13, 2019, 16:40 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt Model/View проблема с битыми индексами [РЕШЕНО]  (Прочитано 1271 раз)
nvek
Самовар
**
Offline Offline

Сообщений: 192



Просмотр профиля
« : Декабрь 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 как вставить спойлер?
« Последнее редактирование: Декабрь 20, 2017, 11:12 от nvek » Записан
ssoft
Бывалый
*****
Online Online

Сообщений: 454


Просмотр профиля
« Ответ #1 : Декабрь 18, 2017, 17:04 »

QModelIndex генерируется всегда с помощью метода

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

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

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

Сообщений: 2070



Просмотр профиля
« Ответ #2 : Декабрь 18, 2017, 23:05 »

ИМХО, пригодится
http://www.prog.org.ru/topic_31100_0.html
Записан
nvek
Самовар
**
Offline Offline

Сообщений: 192



Просмотр профиля
« Ответ #3 : Декабрь 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 это структура где хранятся сами элементы
да, возможно где то есть обработчик селект, но элемент то я не выделяю, а навожу на него всеголишь
Записан
nvek
Самовар
**
Offline Offline

Сообщений: 192



Просмотр профиля
« Ответ #4 : Декабрь 20, 2017, 11:12 »

Я знаю в чем проблема, в методе где обновляется элементы, надо следить, если удаляешь объект, то надо и удалить соответствующий индекс, и если переносишь объект (был std::swap( ) ) то надо и индексы модели свапать beginMoveRow();
интересно еще то, что когда переносится индекс, вместе с ним переносится hover
« Последнее редактирование: Декабрь 20, 2017, 11:36 от nvek » Записан
nvek
Самовар
**
Offline Offline

Сообщений: 192



Просмотр профиля
« Ответ #5 : Декабрь 20, 2017, 15:39 »

Только я вот понять не могу, как происходит или как может происходить ошибка если bebinInsert/endInsert написать отдельно либо до добавления, либо после добавления
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.095 секунд. Запросов: 22.