如何通过字符串 ID 查找 QML 项目?

How to find QML item by its string id?

我有一个对象字符串 id,我需要在 QML 树中找到它。 例如:

var idToFind = "myBtnId"

我可以做类似下面的事情吗?

var objectThatINeed = myMainWindow.findObjectById(idToFind)

据我所知,我可以使用 objectName 来达到这个目的(至少在 C++ 中)。我仍然可以在不引入名称的情况下以某种方式重用现有的 id 吗?

我想将此对象用作其他一些动态创建控件的父对象。

不,您必须使用 objectName 或其他一些 属性。

The id Attribute:

Once an object instance is created, the value of its id attribute cannot be changed. While it may look like an ordinary property, the id attribute is not an ordinary property attribute, and special semantics apply to it; for example, it is not possible to access myTextInput.id in the above example.

QJSValue MyEngine::getQmlObjectById(const QString& id) {
    QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_JSEngine);
    QV4::Scope scope(const_cast<QV4::ExecutionEngine *>(v4));
    QV4::ScopedString name(scope, v4->newString(id));
    return QJSValue(v4, v4->currentContext->getProperty(name));
}

如果您事先知道所需的所有项目的 ID,则可以为它们创建对象映射并使用它来查找它们。例如:

Item {
    property var idMap: ({ foo:foo, bar:bar })
    Rectangle { id:foo }
    Item { id:bar }

    function findItemById(id) {
      return idMap[id];
    }

    Component.onCompleted: console.log(findItemById('foo'), findItemById('bar'))
    // qml: QQuickRectangle(0x1479e40) QQuickItem(0x148fbf0)
}

根据 Phrogz 的回答,如果您不想要显式映射,您可以将组件分配给属性,然后使用 [] 运算符引用它们:

Item {
    id: page
    property Component foo: Rectangle { color: "yellow" }
    property Component bar: Item {  }

    Component.onCompleted: console.log(page["foo"], page["bar"])
    //qml: QQuickRectangle(0x...) QQuickItem(0x...)

}