【问题标题】:QObject::findChild() returns None without obvious reasonQObject::findChild() 在没有明显原因的情况下返回 None
【发布时间】:2014-04-09 16:33:19
【问题描述】:

我是 Qt Quck 和 Qt5/PyQt 的新手,现在我遇到了一个奇怪的问题。我试图在下面的 QML 定义中找到一个对象名称为“test”的对象,如下所示:

self.rootObject().findChild(QObject, "test")

但是调用返回 None。但是,如果我将 objectName: "test" 属性移动到父 Tab 元素,则可以成功找到它。只是在孩子Item 里面找不到。同样,addChannelmodifyChannelremoveChannel 对象也不会被 findChild() 找到。

import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.1
import "TouchStyles"

Item {
    ListModel { }

    TouchButtonFlatStyle { id: touchButtonFlat }
    TouchTabViewStyle { id: touchTabView }

    Rectangle {
        width: 480
        height: 230

        TabView {
            currentIndex: 0
            tabPosition: 1
            anchors.fill: parent
            style: touchTabView

            Tab {
                title: "Play"

                Item {
                    anchors.fill: parent
                    PianoKeyboard { anchors.centerIn: parent }
                }
            }
            Tab {
                title: "Channels"
                Item {
                    objectName: "test"
                    ListView {
                        anchors.fill: parent
                        model: listModel
                        delegate: Channel {}
                    }
                    BorderImage {
                        border.bottom: 8
                        anchors.bottom: parent.bottom
                        source: "images/toolbar.png"
                        width: parent.width
                        height: 50

                        RowLayout {
                            anchors.verticalCenter: parent.verticalCenter
                            anchors.horizontalCenter: parent.horizontalCenter

                            Button { text: "Add"; objectName: "addChannel" }
                            Button { text: "Modify"; objectName: "modifyChannel" }
                            Button { text: "Remove"; objectName: "removeChannel" }
                        }
                    }
                }
            }
        }
    }
}

我做错了什么? Qt 文档说搜索是递归执行的。为什么不遍历整个对象树?

【问题讨论】:

  • 最好的办法是首先检查 C++ 中的搜索是否成功。如果没有,请将其报告为 Qt 错误。否则,这将是一个 PyQt 错误。
  • self.rootObject().findChildren(QObject)(即所有孩子)的结果是什么?
  • 第一个选项卡是否会发生同样的事情(所以如果您将第二个选项卡的项目复制到第一个选项卡)?或者,如果您在执行 findChild 之前选择第二个选项卡,同样的问题?
  • @Schollii,我把2nd tab的内容移到了第一个,然后找到了item(也找到了addChannel item)。当它在第二个选项卡中时,它没有找到 o_O
  • 现在更奇怪了:我给每个 Tab 一个唯一的objectName,我首先为 Tab 执行 findChild(),然后使用找到的 Tab,调用它的 findChild()获取 Tab 的子元素。你猜怎么着?子 Tab 总是会被找到(不管它是否是第一个 Tab),但 Tab 内的子元素只有在 Tab 是第一个时才会被找到。

标签: qt pyqt qml qt5 pyqt5


【解决方案1】:

问题与选项卡仅在需要时“实例化”这一事实有关。第一个选项卡总是被实例化,所以如果你把objectName 放在那里,它就会被找到。

仅当您实例化第二个选项卡(选择它)时,它才会在第二个选项卡中找到。同样,在TabView 上使用findChild 可能会实例化每个选项卡(因为它正在寻找它们),因此即使没有选择第二个选项卡,findChild 也可以工作。

结论:首先实例化所有选项卡(在TabView 上执行findChild 是一种方法,但可能是一种hack),然后为该项目执行findChild

【讨论】:

  • 我在根元素上执行findChild找到TabView(找到),然后在TabView上执行findChild找到Tab(找到),然后在Tab上执行findChild到找到按钮(未找到)。如果我在台式 PC 上运行它(之前我在嵌入式 ARM 板上测试过),问题就会重现。所以,findChild 没有实例化 Tab。另外,我查看了TabView的源代码,除了TabView的样式,我没有发现任何延迟加载逻辑。在找到的 Tab 上运行 findChildren(QObject) 会返回两个子项:一个 QObject 和一个 QQmllComponent。
  • 通过连接到onCurrentIndexChanged 事件TabView 解决。一旦事件被触发,获取活动TabcurrentIndex,然后,根据调用函数的索引连接到(现已实例化的)Tab 子级的信号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多