如何调试错误“无法读取 null 的属性”

Posted

技术标签:

【中文标题】如何调试错误“无法读取 null 的属性”【英文标题】:How to debug error "Cannot read property of null" 【发布时间】:2018-03-28 09:31:06 【问题描述】:

在大型 QML 项目中,有时我会收到以下错误:

MyItem.qml:8: TypeError: 无法读取 null 的属性

当我查看相关行时,它始终位于子项中,属性绑定到父属性,如

Item

    id: myItem

    ASubItem
    
         id: subItem
         width: parent.width
    

所以看起来父项变为 null 并且内部项在此之后尝试更新其属性。

我们有时会从 C++ 中删除项目,因为我们想创建新项目,这似乎是错误消息的原因。我们还从 C++ 创建了一些项目(使用QQmlComponent)并将父项和父项设置为包含这些项目的QQuickItem,但似乎我在其他项目上也遇到了这个错误。

但我不明白为什么内部项会在父项为空时尝试更新自己,不应该同时删除它吗? 有什么方法可以调试它以查看父项何时被删除以及其子项何时尝试更新?

【问题讨论】:

您是否在动态创建那些在运行时销毁的 qml 对象? doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html @talamaki 它们是动态创建的,是的,但是从 C++ 开始,我看不到如何使用文档对我的用例所说的内容 @ymoreau 你找到解决办法了吗?我面临同样的问题 - 当应用程序关闭时,我从动态创建的 QML 窗口的子窗口中获得有关 TypeError 的警告列表,我在其中设置了一些属性,如“parent.something ...” 我们最终进行了大量检查以防止出现警告,因为我们发现它们毫无用处:width: parent?parent.width:0;。尽管此模式对主要对象进行两次评估。如果不是parent,而是将whateverComplexExpression 作为主要对象,它将计算两倍的表达式,从而降低性能。 【参考方案1】:

一种对我有用的解决方法,但是我的情况有点不同,因为我是从 Javascript 而不是 c++ 动态创建对象,但我相信你可以弄清楚如何从 c++ 中做到这一点。

我将 QGuiApplication 实例传递给根 QML 上下文

    engine.rootContext()->setContextProperty("KApp",&app);

然后建立这个连接

    Connections 
    target: KApp;
    onAboutToQuit:
        dynamicallyCreatedObject.destroy();
    

所以重点是,当发出aboutToQuit() 信号时,您必须销毁动态创建的 QML 对象

【讨论】:

以上是关于如何调试错误“无法读取 null 的属性”的主要内容,如果未能解决你的问题,请参考以下文章

嵌套网格中的 ExtJS 错误:无法读取 null 的属性“isGroupHeader”

未捕获的类型错误:无法读取 null 的属性“道具”

未捕获的类型错误:无法读取 null 的属性(读取“添加”)

未捕获的类型错误无法读取 null 的属性(读取“查询选择器”)

角度错误:无法读取 null 的属性(读取“控件”)

为啥我会收到此错误:未捕获的类型错误:无法读取 null 的属性 'classList'