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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QTreeView+QAbstractItemModel+QSortFilterProxyModel: вставка строки дает Segfault  (Прочитано 6059 раз)
Kanareyka
Гость
« : Октябрь 22, 2013, 11:06 »

Пытаюсь скомбинировать QTreeView + QAbstractItemModel + QSortFilterProxyModel.

Когда вместе работают QTreeView + QAbstractItemModel – все нормально.
Когда я в эту конструкцую добавляю QSortFilterProxyModel между TreeView и source model – все разваливается Грустный
Что именно происходит: при вставке новой строки выпадает segmentation fault, причем это происходит очень часто,
но нестабильно, иногда удается вставить строку без ошибки.

Отладка показала, что ошибка появляется уже после того, как мой код insertRow отработал.
Вот на скрине стек выполнения (в стеке нет моего кода) и crash point:
http://i047.radikal.ru/1310/f9/2833f1f5d077.jpg

Т.к. непосредственно мои куски кода проблем не вызывают (проблема появляется после) -
сделала минимальный пример, чтобы продемонстрировать проблему в целом:
http://rapidshare.com/share/06FB98367B2C08268216D7EDDEF771EE
(дублирую вложением в пост)

В нем есть некоторая избыточность:
- TreeView не напрямую вставлен в MainWindow, а сначала в QDialogue (который вставлен в MainWindow);
- начальные данные неприлично захардкодены (см. ExObject constructor);
- оставлен расчет поля order.

Чтобы увидеть ошибку:
- открываем и собираем проект;
- запускаем: видим в окне поле текстового ввода и дерево;
- выбираем в дереве ветку: например x20 (в смысле - мышкой в нее тыкаем, чтобы selection был);
- ставим курсор в поле текстового ввода, печатаем “x25” и жмем Enter;
- предполагается, что новая ветка x25 будет вставлена после x20 (после выбранной ветки).
Если ветка вставилась - повторить аналогичные действия пару-тройку раз - segmentation fault не заставит себя ждать.
Если все равно все нормально работает - разверните ветку x20 и вставьте новую ветку после x201 (вложенную в x20).

Моя текущая среда:
 Qt Creator 2.8.1 Based on Qt 5.1.1 (MSVC 2010, 32bit) Built at13:35:01, Aug 26 2013 Revision c3ed746c24
 Qt 5.1.1 (не знаю, как revision посмотреть)
 MinGW 4.8
Те же проблемы были на Qt Creator 2.7.1 + Qt 5.1.0 + MinGW 4.8

Это в моем коде что-то не так (я пропустила какие-то важные действия)? Библиотека так работает?
Может у кого уже есть рабочий пример связки QTreeView + QAbstractItemModel + QSortFilterProxyModel?
« Последнее редактирование: Октябрь 22, 2013, 11:14 от Kanareyka » Записан
unkeep
Гость
« Ответ #1 : Октябрь 22, 2013, 17:15 »

если после вставки вылетает, то мне кажется проблема где-то в сортировке. попробуй закоментить код в filterAcceptsRow, а вместо него оставь return false;
или может быть в data(). Закоменти тело и вызови в нём sourceModel()->data(mapToSource(index), role).

и пробежись по всем индексам, посмотри, может где-то mapToSource/mapFromSource забыла...
Записан
Kanareyka
Гость
« Ответ #2 : Ноябрь 01, 2013, 19:04 »

Снова здравствуйте!
Прошу прощения за долгое молчание, мне наконец снова удалось заняться этим проектом.

Рекомендации не помогли - точно так же получаю segfault на попытку добавления строки.
Точно так же в режиме отладки вижу


QSortFilterProxyModel: index from wrong model passed to mapFromSource
ASSERT: "!"QSortFilterProxyModel: index from wrong model passed to mapFromSource"" in file itemmodels\qsortfilterproxymodel.cpp, line 398
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.


(только в filterAcceptsRow не "return false;", a "return true;", иначе данные вообще не отображаются).

Что еще можно проверить или поменять?
Записан
unkeep
Гость
« Ответ #3 : Ноябрь 04, 2013, 17:42 »

Цитировать
QSortFilterProxyModel: index from wrong model passed to mapFromSource
это означает, что где-то индекс из прокси используется в исходной модели или наоборот.А  такого быть не должно.

В твоём случае ты скорее всего при вставке вызываешь insertRow у модели источника, а передаешь ему индекс прокси. (индекс полученный от TreeView кстати тоже относится к  прокси)

Если так, то надо или вызывать insertRow у прокси с её же индексом, или преобразовывать прокси индекс в исходный c помощью mapToSource

и пробежись по всем индексам, посмотри, может где-то mapToSource/mapFromSource забыла...
« Последнее редактирование: Ноябрь 04, 2013, 17:44 от unkeep » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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