How to get QML object's id property using C++ API

Luk*_*uke 3 c++ qt qml

I need to parse a QML tree and get ids of all QML objects along the way which have it. I noticed that ids don't behave like normal properties (see the example below) – value returned from obj->property call is an invalid QVariant.

我的问题是 - 有没有办法检索 object's id,即使是一些hacky(但可复制)的方式?

简化示例:

主.qml:

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true

    Item {
        id: howToGetThis
        objectName: "item"
    }
}
Run Code Online (Sandbox Code Playgroud)

主.cpp:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QTimer>
#include <QDebug>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    QTimer::singleShot(1000, [&]() {
        auto item = engine.rootObjects()[0]->findChild<QObject*>("item");
        qDebug() << item->property("objectName");
        qDebug() << item->property("id");
    });

    return app.exec();
}
Run Code Online (Sandbox Code Playgroud)

输出:

QVariant(QString, "item")
QVariant(Invalid)
Run Code Online (Sandbox Code Playgroud)

小智 5

我认为你需要的是:

QString QQmlContext::nameForObject(QObject *object)
Run Code Online (Sandbox Code Playgroud)

你可以在这里找到描述:https : //doc.qt.io/qt-5/qqmlcontext.html#nameForObject

返回此上下文中对象的名称,如果对象未在上下文中命名,则返回空字符串。对象由 setContextProperty() 命名,或者在 QML 创建的上下文的情况下由 ids命名。


根据收到的评论,一个常见的陷阱是nameForObject使用错误的QQmlContext. (当这种情况发生时,你只是空字符串。)为了帮助解决这个问题,这里有一个更完整的例子:

  QQuickItem* const focus_item = my_QQuickWindow->activeFocusItem();
  if (!focus_item) {
    fprintf(stderr, "no item has focus");
  } else {
    // There are many contexts in a hierarchy. You have to get the right one:
    QQmlContext* const context = qmlContext(focus_item);
    if (!context) {
      // Unsure if this branch of code is even reachable:
      fprintf(stderr, "item is not in any context?");
    } else {
      const QString focus_item_id = context->nameForObject(focus_item);
      fprintf(stderr, "focus item: %s\n", focus_item_id.toStdString().c_str());
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • @Luke`qmlContext(item)-&gt;nameForObject(item)` 怎么样? (2认同)
  • 非成员函数:https://doc.qt.io/qt-5/qqmlengine.html#qmlContext (2认同)