2

I have a custom QML type written in C++, the classname is MyCustomType and it's located in the files mycustomtype.h and mycustomtype.cpp.

In the main.cpp file the QML type is made available:

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

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

In the main.cpp file I can get access to the engine's root object like this:

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

My issue is that I need access to that rootObject from within the MyCustomType class in the mycustomtype.cpp file. Is that possible?

The only way I could think of was to pass the rootObject to the constructor. But since the MyCustomType is instatiated in the QML document, and not in C++ code, this solution won't work.

Any ideas?

3
  • 1
    Why do you need to access to the root object? This will help to answer your question. Do you need access to the parent of your object? A set of properties you added in the root object ? Access to the application window? Ability to call signal or functions of the root? etc. Commented Dec 4, 2017 at 9:47
  • The MyCustomType is setting up a video stream using GStreamer and I need to start the pipeline using the method scheduleRenderJob from the rootObject (QQuickWindow). Commented Dec 4, 2017 at 10:07
  • 1
    If your type is a QQuickItem you can use QQuickItem::window() to access the window where the item is rendered. Commented Dec 4, 2017 at 10:54

2 Answers 2

1

I found a solution based on GrecKo's comment.

Instead of making MyCustomType extend QObject, I made it extend QQuickItem. Then it's possible to call window() from anywhere in that class and get the root object. This is simple and it works.

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();    
}
Sign up to request clarification or add additional context in comments.

Comments

0

Method 1: Passing the root object

You can use setContextProperty to make a variable globally available in QML:

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

Now you can access the root object in QML using rootObject and pass it to MyCustomType during construction.

Method 2: Make the root object statically available

You can make the root object statically available. One clean solution is to create a singleton class with all your global data members.

2 Comments

@KMK: If you instantiate it in QML, than that is exactly the way to do it. It is not recommended to use C++-code to access the object tree, to fetch or inject objects from there, as this would require a deep knowledge of the object tree.
@m7913d: I tried to implement it, but ran into a problem because the context property of the rootObject was set after the QML view had been interpreted. I couldn't find a clean way to receive a signal when rootObject changed, so I went with a solution based on GrecKo's comment. Thanks anyway :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.