Последние несколько дней я пытаюсь решить эту странную аварию, которая происходит только в OS X 10.10. Я немного изменил QtTreePropertyBrowser с кнопками внутри строк свойств:
Эти кнопки генерируют сигналы при нажатии, и некоторые действия вызвали очистку дерева и его повторную сборку. К сожалению, это вызывает сбой.
Я думал, что это из-за очистки дерева внутри обработки сигнала, но постановка его в очередь через 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
или же
QTreeModel::data(QModelIndex const&, int) const + 46
QAccessibleTableCell::state() const + 347
QCocoaAccessible::hasValueAttribute(QAccessibleInterface*) + 58
[QMacAccessibilityElement accessibilityAttributeNames] + 398
NSAccessibilityEntryPointAttributeNames + 115
[NSObject(NSAccessibilityInternal) _accessibilityAttributeNamesClientError:] +
Аварийный код выглядит следующим образом:
а также
Основываясь на коде, это кажется мне ошибкой в TreeModel, где некоторые индексы не очищаются после удаления модели дерева. К сожалению, я не являюсь разработчиком Mac (но Windows) и не могу полностью понять, что происходит с индексами из-за не полностью работающего отладчика в QtCreator. Но на основании аварии кажется, что в обоих случаях item
неверный указатель
Иногда помогает установить фокус на другой виджет перед очисткой дерева свойств (как я описал здесь). Но это исправление не всегда работает, и иногда приложение по-прежнему падает.
Я уже извлек весь код из основного приложения и создал минимальный контрольный пример. Я много чего перепробовал, но безуспешно.
Что не работает:
Что работает:
Вот пример того, как происходит сбой приложения: 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
Я буду рад любым идеям или помощи по этой проблеме (платная помощь, если это разрешено здесь). Пожалуйста, дайте мне знать, если потребуется дополнительная информация.
Вся проблема была в реализации Qt Accessibility на OS X.
Когда активный элемент в дереве проекта изменяется, также обновляется QAccessibleTableCell, к сожалению, когда активный элемент не выбран (индекс недействителен), QAccessibleTableCell не обновляется.
Благодаря этой очистке дерево свойств вызывало сбой, потому что QAccessibleTableCell пытался получить доступ к недопустимым данным.
Я написал более подробное описание в моем блоге.