【问题标题】:QML - Accessing model data via qml 'var' corrupts the data SIGSEGVQML - 通过 qml 'var' 访问模型数据会破坏数据 SIGSEGV
【发布时间】:2018-11-20 09:38:29
【问题描述】:

我有一个 QVector<CConfiguration*> 列表作为我的 ListView 的数据源。我动态创建这些对象并将其设置为 ContextProperty。

qmlRegisterUncreatableType<CConfiguration>("DataObjects", 1, 0, "Configuration",QStringLiteral("Configuration should not be created in qml."));
configs.load();
engine.rootContext()->setContextProperty(QStringLiteral("configurations"), &configs);

到目前为止一切都很好。 ListView 显示所有数据都很好。 当我现在尝试访问单个数据对象时。

var item    = configurationsModel.get(3);

这个对象后来被破坏,当我滚动 LIstView 后给我一个 SIGSEGV。 get 方法返回一个 CConfiuration*

感谢您的想法或帮助

【问题讨论】:

标签: qt qml


【解决方案1】:

没有看到你的代码,我猜你看到的问题是one of ownership

当数据从 C++ 传输到 QML 时,数据的所有权 始终使用 C++。 这个规则的例外是当一个 QObject 从显式 C++ 方法调用返回:在这种情况下,QML 引擎假定对象的所有权,除非该对象的所有权 对象已通过调用显式设置为保留在 C++ 中 QQmlEngine::setObjectOwnership() 与 QQmlEngine::CppOwnership 指定。

此外,QML 引擎尊重正常的 QObject 父级 Qt C++ 对象的所有权语义,并且永远不会删除 QObject 有父级的实例。

解决方法是明确设置所有权:

QQmlEngine::setObjectOwnership(&configs, QQmlEngine::CppOwnership);

或者给对象一个父对象(在堆上分配之后):

Configs *config = new Configs(&application);
configs->setParent(&application)

无论您选择哪个选项,都必须在设置上下文属性和加载应用程序的 QML 之前完成。

【讨论】:

  • 感谢您的帮助。我是 qml 的新手,所以我不熟悉所有权转移的概念。第一种方法(显式集所有权)没有解决问题。第二个方法(设置父关系)确实有效。
  • 我仍然有点不确定何时在堆栈上创建我的对象以及何时需要将它们放在堆上以使 Qt / QML 快乐。有没有关于这个主题的文档?
  • 实际上,设置所有权是一种已知可行的解决方案,已知具有父对象的对象在与模型一起使用时仍被 qml 引擎意外删除,这是最近才出现的一个错误已修复,但在 qt 5.12 发布之前不会发布,可能在今年年底左右 - bugreports.qt.io/browse/QTBUG-50319
  • 第三天没有崩溃。我认为这是解决方案。 @Mitch:您对 Qt/qml 有丰富的经验。也许你也可以看看我的其他问题 - 请;-)
  • 不幸的是,我在线程方面的经验很少,所以我不会提供太多帮助。
猜你喜欢
  • 1970-01-01
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多