Search code examples
windowqmlhwnd

QML get the winId of a loaded qml window


I would like to get the winId of a qml window. I have the following files.

main.qml :

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

Window {
    id: myMainWindow
    title: "MyMainWindow"

    width: 200
    height: 200;
    visible: true

    Component.onCompleted: {
        x = 40
        y = 40
    }
}

and my main.cpp :

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QWindow>

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

    QQmlApplicationEngine engine;
    qmlRegisterType<FbItem>("fbitem", 1, 0, "FbItem");
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    QObject* m_rootObject = engine.rootObjects().first();
    auto rect_area = m_rootObject->findChild<QWindow*>("myMainWindow"); //the id of the Window in qml

    //both lines make the application crash
    //HWND hWnd = reinterpret_cast<HWND>(rect_area->winId());
    WId wid = rect_area->winId();

    return app.exec();
}

The crash message is :

The inferior stopped because it triggered an exception.
Stopped in thread 0 by: Exception at 0x13500da, code: 0x0000005: read access violation at: 0x0, flags=0x0 (first chance).

What is wrong? How can I get the winId of my window?

EDIT : we can see that rect_area is still bad. In edited main.qml :

Window {
    id: _component
    objectName: "myMainWindow"
    ...
}

enter image description here


Solution

  • Ok, as I noticed in comment you always have to check value returned by findChild. Second, findChild looks by objectName, not by id as you wrongly assumed. But in your case it just a recommendation. Your problem that myMainWindow is already root item (ie Window item) so m_rootObject is what you need. So you try to search item inside the item itself and validly get null. To get the Window you only need:

    QObject* m_rootObject = engine.rootObjects().first();
    if(m_rootObject) {
        QWindow *window = qobject_cast<QWindow *>(m_rootObject);
        if(window) {
            WId wid = window->winId();
        }
    }
    

    Sure, this code is excessive, I just want to show the idea.