如何使用C++ API获取QML对象的id属性

3
我需要解析一个QML树并获取其中所有带有id的QML对象的id。我注意到id不像普通属性一样(请参见下面的示例)- 从obj->property调用返回的值是无效的QVariant
我的问题是 - 是否有一种方法可以以某种hacky(但可重现的)方式检索对象的id
简化示例:
main.qml:
import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true

    Item {
        id: howToGetThis
        objectName: "item"
    }
}

main.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();
}

输出:

QVariant(QString, "item")
QVariant(Invalid)

如果我可以使用 objectName,我就会使用它。被接受的答案提供的解决方案正是我想要的。 - Luke
1个回答

5

我认为你需要的是:

QString QQmlContext::nameForObject(QObject *object)

您可以在此处找到说明: https://doc.qt.io/qt-5/qqmlcontext.html#nameForObject

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


根据收到的评论,常见的错误是使用错误的QQmlContext调用nameForObject。(当发生这种情况时,只会返回空字符串。)为了帮助解决这个问题,以下是一个更完整的示例:

  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());
    }
  }

不幸的是,以下代码输出一个空字符串:qDebug() << engine.rootContext()->nameForObject(item); - Luke
2
@Luke,qmlContext(item)->nameForObject(item)怎么样? - GrecKo
@GrecKo 你具体是什么意思 - qmlContext是什么? - Luke
2
一个非成员函数:https://doc.qt.io/qt-5/qqmlengine.html#qmlContext - GrecKo
1
@GrecKo 非常感谢!这个代码像预期的一样工作:qmlContext(item)->nameForObject(item); - Luke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接