QObject::findChild() returns None without obvious

2019-07-15 11:09发布

问题:

I'm new to Qt Quck and Qt5/PyQt, and now I've faced a strange problem. I'm trying to find an object with objectName "test" in the below QML definition like this:

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

But the call returns None. However, if I move the objectName: "test" property to the parent Tab element, then it's found successfully. It's only not found whem inside the child Item. Similarly, addChannel, modifyChannel and removeChannel objects are also not found by 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" }
                        }
                    }
                }
            }
        }
    }
}

What am I doing wrong? The Qt documentation says that the search is performed recursively. Why doesn't it traverse the entire object tree?

回答1:

The problem is related to the fact that tabs are "instantiated" only on demand. The first tab is always instantiated, so if you put the objectName there it will be found.

It will be found in the second tab only if you instantiate the second tab (select it). Similarly, using findChild on the TabView probably instantiates each tab (since it looking for them), so after that a findChild works even if second tab was not selected.

Conclusion: instantiate all tabs first (doing a findChild on the TabView is one way but may be a hack), then do the findChild for the item.



标签: qt pyqt qml qt5 pyqt5