清除QtPropertyBrowser / QTreeModel时崩溃

时间:2015-05-21 13:44:45

标签: c++ qt treemodel

最近几天我正在尝试解决仅在OS X 10.10上发生的这种奇怪的崩溃。我稍微修改了QtTreePropertyBrowser,其中包含属性行中的按钮:

这些按钮在单击时会发出信号,某些操作会导致清除树并再次重建。不幸的是,这会导致崩溃。

我认为这是因为在信号处理中清除了树,但是通过QEvent排队却无济于事。问题是崩溃有时也会在树被清除后的某个时间发生。

所有崩溃都以这两个callstack中的一个结束:

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都不是有效的指针。

有时候有用的是在清理属性树之前将焦点设置到不同的小部件(如我在此处所述)。但是这个修复程序并不总是有效,有时候应用程序仍会崩溃。

我已经从主应用程序中提取了所有代码并创建了最小的测试用例。我尝试了很多但没有成功。

什么不起作用:

  • 在清除之前从窗口停用焦点
  • 通过创建带动作的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

我会很高兴有任何想法或帮助解决这个问题(如果允许,也可以获得帮助)。如果需要更多信息,请与我们联系。

1 个答案:

答案 0 :(得分:0)

整个问题出现在OS X上的Qt Accessibility实现中。

当项目树上的活动元素发生更改时,QAccessibleTableCell也会更新,不幸的是,当取消选择活动元素时(索引无效),QAccessibleTableCell不会更新。

由于此清除,属性树导致崩溃,因为QAccessibleTableCell尝试访问无效数据。

我写了更详细的说明on my blog