最近几天,我试图解决这个仅在 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
或者
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 beta 重新编译测试项目
- 在旧版 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
我会很高兴有任何想法或帮助解决这个问题(如果这里允许的话,也有付费帮助)。如果需要更多信息,请告诉我。