Название: Как работает BeginINsertRow и ему подобные? Отправлено: nvek от Декабрь 24, 2017, 10:40 В документации сказано что надо обновление своей структуры заносить в
Код: beginInsertRow() Код: addChild() Код: beginInsertRow() будет ошибка, даже если это делать в одной и той же функции. почему? как это работает? Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: Авварон от Декабрь 24, 2017, 12:46 При удалении, например, перерасчитывается выделенная строка - если она попала в удаленную область (напирмер, удаляем индексы 5-9), то её надо подвинуть на первый индекс после области (или на парента, если области нет) (10й).
Если вы сперва удалите данные, а потом кинете сигнал, то методы index() и parent() для модели будут давать неверные данные - вью запрашивает 10й индекс, а его уже нет (он теперь 5й). Если вы сперва кинете сигналы, а потом удалите данные, то будет неверно вызвана отрисовка - на момент отрисовки вью считает, что индексов нет, а они ещё есть. Т.е. она отрисует старые данные и не отрисует часть оставшихся. И это только глядя на QAbstractItemView (https://github.com/qt/qtbase/blob/5.10/src/widgets/itemviews/qabstractitemview.cpp#L3363), в случае того же QTreeView надо пересчитывать внутреннюю таблицу, которая живет в нём. Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: nvek от Декабрь 25, 2017, 13:58 понимаю почему, но не понимаю как ???
Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: nvek от Декабрь 25, 2017, 14:22 опять же, есть простой метод:
Код:
вначале я говорю чтобы обновилась вьюшка, а затем говорю чтобы удалился элемент. даже когда после begin делать так, чтобы rowCount выводил на элемент меньше, все равно падает. Почему так нельзя делать , какая причина этому? Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: kuzulis от Декабрь 25, 2017, 14:42 Не надо ничего вьюшке говорить, т.к. модель сама скажет ей. Именно поэтому нужно все делать в правильном порядке с begin/end.
Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: nvek от Декабрь 25, 2017, 16:28 да, в правильном, не спорю, интересен другой вопрос, как это все происходит?
Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: deMax от Декабрь 26, 2017, 08:39 Предположу: т.к. данные в моделе могут вообще не храниться(например таблица умножения). Компилятору нужно понять когда в таблице что то измениться чтобы пересчитать данные для отображения.
begin - сохраняет первоначальное состояние, end - смотрит нужные изменения(если insert то значит только добавляли) и обновляет в отображение только то что изменилось. можно один refresh - но тогда придется для всех ячеек вызвать получение новых данных и обновлять всю таблицу. Тогда при удалении строк в самом начале(вне видимости виджета) таблица будет смещена. Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: nvek от Декабрь 26, 2017, 13:20 смотрю в исходниках как все идет
beginRemoveRow(){если правильно понимаю, там просиходит добавление в стек тех индексов. которые подвержены изменению (те самые индексы, которые мы подали)} посылает сигнал -> emit rowsAboutTobeRemoved(const QModelIndex& parent, int first, int last) а затем вызывает свой метод rowsAboutTobeRemoved(const QModelIndex& parent, int first, int last) смысл такой, что в endRemoveRows() в конце вызывается метод removeRow() и после него emit removeRow() эти сигналы соединены с QAbstractItemViewPrivate то есть с нашим представлением видимо, внутри этих сигналов идет запоминание индексов, затем ихнее удаление но все равно не понимаю, вначале идет begin потом end все вроде удалилось. дальше я удаляю из своей структуры m_childItems.remove(i); поидее , если синхронизировать это с тем, чтобы rowCount показывал на единицу меньше, то все должно работать. Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: Авварон от Декабрь 26, 2017, 18:53 Ну, если rowCount/index/parent/data будут возвращать новые данные, то всё будет ок:)
Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: nvek от Декабрь 28, 2017, 06:47 вот у меня не работает. Падает на паренте при перерисовке. в Парент приходит невалидный указатель по валидному индексу.
Как это работает??? ??? ??? И это случается я так думаю из-за хавера, который елозит по treeView Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: nvek от Декабрь 28, 2017, 07:06 Опять же повторюсь, что при правильном подходе все работает правильно, но мне безумно интересно, почему. Уже второй день мучию исходники qt
Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: nvek от Декабрь 28, 2017, 07:58 точно знаю, что в этом всем деле, замешан hover
Код: //qtreeview.cpp QTreeView::drawRow Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: Igors от Декабрь 28, 2017, 08:56 .. но мне безумно интересно, почему.. Это пройдет. Пользуясь либой вы/мы неизбежно в какой-то мере становимся "пользователями". Т.е. не нужно вдаваться в подробности отчего да почему если все работает как положено. Это нормально, главное не слишком увлекаться, не сваливаться в бездумную жратву чужих классов. Ну найдете, ну осознаете - да, "полезно", но особого понимания это не добавит.Название: Re: Как работает BeginINsertRow и ему подобные? Отправлено: nvek от Декабрь 28, 2017, 10:37 Возможно ли такое, что все может быть еще связано с таймером?
данные обновляются по таймингу. Таймер же как я прочитал в книге, полностью ассинхронный. проверял, с евента, мышки до перерисовки вьюшки идет все в одном потоке. Залезая в исходники qt я только все больше постигаю черную магию А может быть такое, что сигналы как-то на системных прерываниях работают? |