ДК
29 мая 2020 г. 22:10

QModelIndex становится не действительным, но валидный

Привет. Есть проблема с индексом и для меня это чистая магия:
Сначала, что делаю: на вьюхе есть редактируемые ячейки. Пользователь редактирует одну, потом внезапно решает не сохраниться и шлепает кнопку, которая модель обновит (но строки и столбцы останутся на месте, просто те же самые данные еще раз обновятся в том же порядке). В итоге, его текст с ячейки пропадет, он же не сохранил его. Вот хочу этот текст восстанавливать.
Также, с вьюхами окна работают разные контроллеры, разделили, чтобы не валить всю логику в одно место. На вход такие контроллеры принимают модель и вьху, всё работает отлично, много логики отрабатывает корректно. Наш - условный ViewController.
Это введение, теперь код.
Как это делаю:
Есть два коннекта

  1. connect(_model, &TreeModel::dataChanged, this, &ViewController::setBufferResult);
  2. connect(_model, &TreeModel::dataReceived, this, &ViewController::setResultsFromBuffer);

в setBufferResult мапплю данные ячейки и индекс QMap(QString, QModelIndex)

  1. void ViewController::setBufferResult(const QModelIndex &index)
  2. {
  3. if(!index.isValid())
  4. return;
  5. if(index.column() == Test::RESULT) {
  6. //resultFromView корректен и сущность по индексу получаю без проблем всегда
  7. const QString resultFromView = _model->item(index)->item().
  8. value<Test*>()->result()->result();
  9. _buffResults.insert(resultFromView, index);
  10. }
  11. }

Клиент наредактировал себе ячеек, и потом следует действие, которое модель обновит. Как только модель обновилась- восстанавливаю данные в setResultsFromBuffer:

  1. void ViewController::setResultsFromBuffer()
  2. {
  3. for(const QString result : _buffResults.keys())
  4. {
  5. const QModelIndex &index = _buffResults.value(result);
  6. //если тут индекс принять вот так QModelIndex index, то ниже отвал будет не всегда
  7. if(index.isValid())
  8. {
  9. //тут валится приложение, хотя индекс какую-то валидность имеет
  10. const QString resultFromView = _model->item(index)->item().
  11. value<Test*>()->result()->result();
  12. if(resultFromView.isEmpty())
  13. {
  14. _model->waitIfBusy();
  15. _model->setData(index, result, Qt::EditRole);
  16. }
  17. }
  18. }
  19. }

Вот и получается, что индекс каким то образом становится не рабочим. Я не понимаю почему, что не так? тем более удивляет, что иногда отрабатывает, хотя, не правильно угадывается строка вставки данных, но ид столбца не "съезжает", если индекс с мапы принять по значению, а не по константной ссылке (см комментарии к коду). Есть подозрения, что это мапа портит...

2

Вам это нравится? Поделитесь в социальных сетях!

4
ДК
  • 1 июня 2020 г. 12:51

Попробовал через другие контейнеры, ничего не поменяло. Значит, после нового отображения модели на вьюхе старые индексы нельзя использовать, несмотря на то, что модель не поменялась?

    Evgenii Legotckoi
    • 1 июня 2020 г. 13:01

    Индексы могу пересоздаваться. Тогда они указываются в другой облавсти памяти и могут указываться на иные указатели данных.

    Важными данными в индексе являются

    • строка
    • колонка
    • модель
    • и ещё какое-то quintptr поле. Там хранится указатель на данные. Скорее всего он и протухает при работе модели.

    Так что вам нужно как-то иначе увязывать данные в буффере

      ДК
      • 1 июня 2020 г. 13:18
      1. inline QModelIndex QAbstractItemModel::createIndex(int arow, int acolumn, quintptr aid) const
      2. { return QModelIndex(arow, acolumn, aid, this); }

      кажется, понял. Сохраню строку\столбец\quintptr и потом создам новый индекс. Спасибо!

        Evgenii Legotckoi
        • 1 июня 2020 г. 13:21

        Не гоните лошадей. quintptr aid вам не нужно сохранять.
        Попробуйте ограничиться только колонкой и строкой. А также используете метод index() вашей модели, чтобы по строке и колонке возвращать нужный индекс.

          Комментарии

          Только авторизованные пользователи могут публиковать комментарии.
          Пожалуйста, авторизуйтесь или зарегистрируйтесь
          • Последние комментарии
          • Evgenii Legotckoi
            16 апреля 2025 г. 17:08
            Благодарю за отзыв. И вам желаю всяческих успехов!
          • IscanderChe
            12 апреля 2025 г. 17:12
            Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
          • AK
            1 апреля 2025 г. 11:41
            Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
          • Evgenii Legotckoi
            9 марта 2025 г. 21:02
            К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
          • VP
            9 марта 2025 г. 16:14
            Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…