[solved] How to create a binding from C++ to a QML property?



  • I have a component in an external QML file. The component is dynamically added like this:

    @
    QUrl url = QUrl (QStringLiteral ("qrc:///MyPage.qml"));

    // Delete the current page.
    
    qDeleteAll (m_pContentArea->children());
    
    // Gain access to the engine and context.
    
    QQmlEngine *pEngine = qmlEngine (m_pContentArea);
    QQmlContext *pCtx = pEngine->contextForObject (m_pContentArea);
    
    // Create the new component.
    
    QQmlComponent component (pEngine, url);
    QObject *pNewPage = component.beginCreate (pCtx);
    
    // parent for the object hierarchy:
    pNewPage->setParent (m_pContentArea); 
    
    // parent property for dynamic bindings:
    pNewPage->setProperty ("parent", QVariant::fromValue<QObject *>(m_pContentArea));
    
    // ...
    component.completeCreate();
    

    @

    So far, so clear. I now basically would like to connect the contentArea's property "height" to be the same as the page's height, with the intention that if the page's height changes, the contentArea's height changes also.

    To set the contentArea's height to some constant value, I could write:

    @
    m_pContentArea->setProperty ("height", QVariant::fromValue<qreal>(1000.0f));
    @

    How can I set the value of the property to be a script? The following doesn't work:

    @
    m_pContentArea->setProperty ("height", QVariant::fromValue<QString>QStringLiteral ("parent.height"));
    @

    I tried also:

    @
    QObject::connect (m_pContentArea, SIGNAL (setHeight (qreal)),
    pNewPage, SLOT (height()));
    @

    But this doesn't work either, because there is no signal called setHeight (qreal).



  • If i'm not mistaken, you need to process signal heightChanged() at main thread - this signal emits when property is changed. At this slot you can request height and set to another component.



  • Thanks for the reply. I'm going to try this. However, I'm interested if there is any chance to install a JavaScript from C++.



  • What do you mean "to install JS from C++"?



  • I mean I want to set the property height to some JavaScript. I tried the following:

    @
    QJSValue wrapper = pEngine->newQObject (pNewPage);
    pEngine->globalObject().setProperty ("curPage", wrapper);
    QJSValue ret = pEngine->evaluate ("curPage.parent.height = curPage.height;");

    if (ret.isError())
    {
        qDebug() << "Error: replaceContentWith: Couldn't connect height property!";
        qDebug() << ret.toString();
    }
    

    @

    Unfortunately, this doesn't work, the error message is: "ReferenceError: curPage is not defined". Which is strange, because I set curPage to be a property of globalObject...



  • I hope "this article":http://qt-project.org/doc/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#accessing-loaded-qml-objects-by-object-name will help you.
    But are you sure that it is correct to set size of any element from C++?



  • I don't just want to set height to some fixed size. I want to set it to a script that will automatically adjust the size of curPage.parent.height as the size of curPage.height changes. In QML, this is very simply done by saying "height: curPage.height;" in the parent object. QML will autmatically create the necessary bindings between slots and signals. I basically want to use the same technique from C++, i.e. I want to set the height property to some script. Your article doesn't mention this, or maybe I missed it...

    Yeah, maybe it's not the correct way to do this. I'm going to try the slot/signal technique with heightChanged as you suggested.



  • I finally solved the problem in a most stupidly simple way! In the component that is dynamically loaded, I added the following:

    @
    Component.onCompleted:
    {
    parent.height = height;
    }
    @

    Cheers!


Log in to reply
 

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