последние несколько дней я пытаюсь решить этот странный сбой, который происходит только в OS X 10.10. Я немного изменил QtTreePropertyBrowser с кнопками внутри строк свойств:
(источник: inventic.eu)
Эти кнопки излучают сигналы при нажатии, а некоторые действия приводили к очистке дерева и его повторному перестроению. К сожалению, это приводит к сбою.
Я думал, что это из-за очистки дерева внутри обработки сигнала, но постановка его в очередь через QEvent не помогает. Проблема в том, что сбой иногда происходит через некоторое время после очистки дерева.
Все сбои заканчиваются одним из этих двух стеков вызовов:
QTreeModel::index(QTreeWidgetItem const*, int) const + 176
QTreeModel::parent(QModelIndex const&) const + 75
QTreeView::isIndexHidden(QModelIndex const&) const + 71
QTreeView::visualRect(QModelIndex const&) const + 93
QAccessibleTableCell::rect() const + 29
QAccessibleTableCell::state() const + 146
QCocoaAccessible::hasValueAttribute(QAccessibleInterface*) + 58
[QMacAccessibilityElement accessibilityAttributeNames] + 398
NSAccessibilityEntryPointAttributeNames + 115
[NSObject(NSAccessibilityInternal) _accessibilityAttributeNamesClientError:] + 56
or
QTreeModel::data(QModelIndex const&, int) const + 46
QAccessibleTableCell::state() const + 347
QCocoaAccessible::hasValueAttribute(QAccessibleInterface*) + 58
[QMacAccessibilityElement accessibilityAttributeNames] + 398
NSAccessibilityEntryPointAttributeNames + 115
[NSObject(NSAccessibilityInternal) _accessibilityAttributeNamesClientError:] +
Код сбоя выглядит следующим образом:
(источник: inventic.eu)
и
Основываясь на коде, мне кажется, что это ошибка в TreeModel, когда некоторые индексы не очищаются после стирания модели дерева. К сожалению, я не являюсь родным разработчиком Mac (но Windows), и я не могу полностью понять, что происходит с индексами из-за не полностью работающего отладчика в QtCreator. Но, судя по сбою, кажется, что в обоих случаях item
не является допустимым указателем.
Что иногда помогает, так это установить фокус на другой виджет перед очисткой дерева свойств (как я описал здесь). Но это исправление работает не всегда, и иногда приложение все равно падает.
Я уже извлек весь код из основного приложения и создал минимальный тестовый пример. Я пробовал много вещей, но безуспешно.
Что не работает:
- деактивировать фокус из окна перед очисткой
- выполнить очистку вне обработки сигнала, создав QEvent с действием
- для очистки дерева свойств один за другим вместо метода clear()
- перекомпилировать тестовый проект с последней бета-версией Qt 5.5
- чтобы скомпилировать приложение на более старой OS X (10.9) и выполнить его на 10.10
Что работает:
- компилировать тот же код на Windows/Linux
- для выполнения того же кода на более старой OS X
Вот пример сбоя приложения: https://dl.dropboxusercontent.com/u/11355235/ShareX/2015-05/2015-05-21_15-28-56.mp4
Самый простой способ выполнить эту ошибку — очистить дерево свойств и открыть любой диалог (который выполняет цикл событий, который, вероятно, вызывает сбой)
on_btnStandaloneDialog_clicked();
m_propertyBrowser->clear();
on_btnStandaloneDialog_clicked();
Минимальное тестовое приложение доступно здесь: https://www.dropbox.com/s/dbnd3inbwpfc6l9/property-tree-crash.zip?dl=0
Буду рад любым идеям или помощи в решении этой проблемы (платная помощь тоже, если она здесь разрешена). Пожалуйста, дайте мне знать, если потребуется дополнительная информация.
item(index);
возвращает недействительный указатель наQTreeWidgetItem
. Проверь это. - person vahancho   schedule 21.05.2015