Import within QQmlComponent not works



  • Hi,

    I'm working with dynamically created QQmlComponents and everthing works fine so far. Unfortunately if I want to import other .qml files from myself I always get the error "ReferenceError: doSomething is not defined".

    File structur:
    \ -> all c++ files
    \qml -> all .qml files

    Qml resource structur:
    /main.qml
    /cont/sub.qml

    main.qml

    import "qrc:/cont/qml"
    
    Window {
        id: iRoot
        objectname: "oWindow"
        visible: true
        ...
    
        function doSomething() {
        }
    }
    

    sub.qml (->QQmlComponent)

    import QtQuick 2.7
    import "qrc:/qml"
    
    Rectangle {
        id: iSub
        ...
    
        onHeightChanged: doSomething()
    

    The same .qml files with static loading or via Loader works fine.

    Do I have to consider something special regarding the import path in a dynamically loaded QQmlComponent? I tried already different constellation, also with absolut path but nothing works.

    Does someone maybe has an idea?

    Thxs in advance...


  • Moderators

    @PowerNow Just importing the directory wont work if you want to access the properties or functions of a certain QML type. You will need to instantiate it and access the function using the root component's id or you could put that function inside a Javascript file and import it.



  • @p3c0 : Thxs for your fast response!

    1.) You will need to instantiate it and access the function using the root component's id:

    m_pEngine = new QQmlApplicationEngine(this);
    m_pEngine->load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
    m_pRootObj = m_pEngine->rootObjects().first();
    
    QQmlComponent placeMapComp(m_pEngine,QUrl(QStringLiteral("qrc:/cont/qml/sub.qml")));
    QQuickItem *pPlaceMapItm = qobject_cast<QQuickItem*>(placeMapComp.create());
    
    QQuickItem *pMapItm = m_pRootObj->findChild<QQuickItem*>("oWindow");
    pPlaceMapItm->setParentItem(pMapItm);
    

    Is the main.qml after loading instantiated? If yes then I should have acess in sub.qml via

    iRoot.doSomething
    

    Unfortunately it does not work.

    Pease, would you maybe have an example for that?


  • Moderators

    @PowerNow Sorry the access through id will only work when the QML component is instantiated from QML only.
    You can do the same from C++ actually as follows(C++11 required):

    QObject::connect(childItem, &QQuickItem::heightChanged, [=](){
        QMetaObject::invokeMethod(rootItem, "doSomething"); 
    });
    

    Info here:
    http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#invoking-qml-methods

    Also since setParentItem requires an Item and oWindow being a Window can't be casted to QQuickItem you will need to use contentItem to be its parentItem.

    QQuickItem *rootContentItem = qvariant_cast<QQuickItem*>(rootItem->property("contentItem"));
    childItem->setParentItem(rootContentItem);
    


  • @p3c0 I see what you mean excepted the entry "[=]()". Please could you explain me this?

    After some considerations I will now use the following method, as you also mentioned. To use properties and Javascript functions together in a.) usually used .qml files via main.qml and b.) dynamically creaded .qml components via QQmlComponents it offers itself using an external Javascript file.

    global.js

    .pragma library
    
    var someVariable = 0;
    
    function doSomething() {
        ...
    }
    

  • Moderators

    @PowerNow

    I see what you mean excepted the entry "=". Please could you explain me this?

    Lambda functions. [=] means captures all variables by value and () contains the parameters.
    In our context this is a part of the new signal and slot syntax as per new features introduced in c++11.
    You can find more info here:
    http://en.cppreference.com/w/cpp/language/lambda


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.