Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

qobject_cast<QQuickItem*> returns nullptr for QQuickDialog1



  • Hi,

    I have been using the following code for loading a dialog from QML:

        QQmlComponent component(&engine_, QUrl("qrc:/dialog.qml"));
        QObject* dlg(component.create());
        QQuickItem* object(qobject_cast<QQuickItem*>(dlg));
    

    After creation, the debugger tells me that dlg is of type QQmlPrivate::QQmlElement<QQuickDialog1> and I can see e.g. the correct dialog title, so I assume that the creation has been successful.
    The pointer 'object' however is nullptr after qobject_cast.
    What is wrong here?

    Many thanks



  • Solved the problem:

    1. Obviously, using Dialog is not possible in the way I wanted
    2. Replacing Dialog with Window and casting to QQuickWindow is working
    3. Do not set the parent window

    So this code is working

        QObject* dlg(component_.create());
        QQuickWindow* object = qobject_cast<QQuickWindow*>(dlg);
    
        QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
    
        dlg->setParent(&engine_);
    

    with the class member component_ having been constructed before:

    component_(&engine_, QUrl("qrc:/some_win.qml"))
    

    The original code I was using was SO based: How to create a QQmlComponent from C++ at runtime


  • Moderators

    QQuickDialog1 class is unrelated to QQuickItem (it only inherits from QObject, see the code), so it fails to cast.



  • Thanks for the answer.
    How could I then load a dialog from a QML?


  • Moderators

    @HJPVVV said in qobject_cast<QQuickItem*> returns nullptr for QQuickDialog1:

    Thanks for the answer.
    How could I then load a dialog from a QML?

    Do it in QML not C++... Or use the QObject pointer, do not try to cast it to QQuickItem.

    I do not understand what you want to achieve so I can't help without more information.



  • My HMI is 'assembled' based on a configuration outside QML.
    When a button is clicked, I want to be able to load a dynamic library containing the C++ handler code which initially loads the QML and handles various signals. This architecture is given.
    I have tried to replace the Dialog in the QML with a Window. Now the cast works, but the window disappears right after creation:

        QObject* win(component_.create());
        QQuickWindow* object = qobject_cast<QQuickWindow*>(win);
    
        QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
    
        object->setParent(window_);
        win->setParent(&engine_);
    

    component_ is a member of the QObject derived class which handles the signal emitted by the button mentioned above.



  • Solved the problem:

    1. Obviously, using Dialog is not possible in the way I wanted
    2. Replacing Dialog with Window and casting to QQuickWindow is working
    3. Do not set the parent window

    So this code is working

        QObject* dlg(component_.create());
        QQuickWindow* object = qobject_cast<QQuickWindow*>(dlg);
    
        QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
    
        dlg->setParent(&engine_);
    

    with the class member component_ having been constructed before:

    component_(&engine_, QUrl("qrc:/some_win.qml"))
    

    The original code I was using was SO based: How to create a QQmlComponent from C++ at runtime


Log in to reply