【问题标题】:Access QML root object from C++ QML type从 C++ QML 类型访问 QML 根对象
【发布时间】:2018-05-17 17:00:13
【问题描述】:

我有一个用 C++ 编写的自定义 QML 类型,类名是 MyCustomType,它位于文件 mycustomtype.hmycustomtype.cpp

main.cpp 文件中,QML 类型可用:

qmlRegisterType<MyCustomType>("MyCustomType", 1, 0, "MyCustomType");

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("../qml/main.qml")));

main.cpp 文件中,我可以像这样访问引擎的根对象:

rootObject = static_cast<QQuickWindow *> (engine.rootObjects().first());

我的问题是我需要从 mycustomtype.cpp 文件的 MyCustomType 类中访问该 rootObject。这可能吗?

我能想到的唯一方法是将 rootObject 传递给构造函数。但由于 MyCustomType 是在 QML 文档中而不是在 C++ 代码中实现的,因此该解决方案将不起作用。

有什么想法吗?

【问题讨论】:

  • 为什么需要访问根对象?这将有助于回答您的问题。您需要访问对象的父级吗?您在根对象中添加的一组属性?访问应用程序窗口?能否调用根的信号或函数?等
  • MyCustomType 正在使用 GStreamer 设置视频流,我需要使用 rootObject (QQuickWindow) 中的方法 scheduleRenderJob 启动管道。
  • 如果您的类型是QQuickItem,您可以使用QQuickItem::window() 访问呈现项目的窗口。

标签: c++ qt qml


【解决方案1】:

我根据 GrecKo 的评论找到了解决方案。

我没有让 MyCustomType 扩展 QObject,而是扩展了 QQuickItem。然后可以从该类中的任何位置调用 window() 并获取根对象。这很简单,而且很有效。

mycustomtype.h:

class MyCustomType : public QQuickItem
{
    Q_OBJECT

public:
    explicit MyCustomType(QQuickItem *parent = 0);

}

mycustomtype.cpp

MyCustomType::MyCustomType(QQuickItem *parent) : QQuickItem(parent)
{
    QQuickWindow *rootObject = window();    
}

【讨论】:

    【解决方案2】:

    方法一:传递根对象

    您可以使用setContextProperty 使变量在 QML 中全局可用:

    engine.rootContext ().setContextProperty("rootObject", QVariant::fromValue(engine.rootObjects().first()));
    

    现在您可以使用rootObject 访问QML 中的根对象,并在构造过程中将其传递给MyCustomType

    方法二:使根对象静态可用

    您可以使根对象静态可用。一个干净的解决方案是创建一个包含所有全局数据成员的单例类。

    【讨论】:

    • @KMK:如果你在 QML 中实例化它,那正是这样做的方式。不建议使用 C++ 代码访问对象树,从那里获取或注入对象,因为这需要对对象树有深入的了解。
    • @m7913d:我尝试实现它,但遇到了一个问题,因为 rootObject 的 context 属性是在解释 QML 视图之后设置的。当 rootObject 更改时,我找不到接收信号的干净方法,因此我采用了基于 GrecKo 评论的解决方案。无论如何谢谢:)
    猜你喜欢
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    相关资源
    最近更新 更多