Dynamically Loading Components



  • Ok, All of the documents seem to suggest that this should be easy, but I'm can't seem to get it.

    What I am trying to:
    I have a main view defined in QML, which contains a PathView. The look of the delegate for that PathView is defined in a separate QML document whose location is not known when constructing the main view.

    I have attempted to do this with the following procedure:

    1. construct a Declarative View using the QML document for the main view.
    2. locate the QML document which defines the look of the delegate, and load it into a QDeclarativeComponent (giving it the engine of the existing view)
    3. In the main QML, Give the PathView a locally defined delegate component which uses the Loader object to create an instance of the actual delegate component.

    This doesn't work. The Loader object seems to have no idea about the existence of the separately loaded component. What am I missing?

    My code looks something like this:

    main.cpp:
    @
    view = new QDeclarativeView(QUrl("qrc:/MainView.qml"));

    QUrl delegateViewURL = findDelegateViewQML();

    QDeclarativeComponent delegateView(view, delegateViewURL);

    delegateView.create();
    @

    MainView.qml:
    @
    Component {
    id: listDelegate

    Loader { sourceComponent: delegateView }
    

    }

    PathView {
    id: pathView
    model: listModel
    delegate: listDelegate
    path: listPath
    }
    @

    delegateView.qml:
    @
    Rectangle {
    width: 100
    height: 100
    color: "grey"

    Component.onCompleted: { console.log("delegateView loaded!"); }
    

    }
    @

    I expect to see a 100x100 grey square inside each PathView element, but they all come up empty. If I define the rectangle directly inside listDelegate, I get the result I want. Even defining the delegateView component inside MainView.qml and loading it with Loader {sourceComponent: delegateView} works great. But if I try to use the separately loaded document, I get the following in the console:

    delegateView loaded!
    qrc:/MainView.qml:46: ReferenceError: Can't find variable: delegateView
    qrc:/MainView.qml:46: ReferenceError: Can't find variable: delegateView
    qrc:/MainView.qml:46: ReferenceError: Can't find variable: delegateView

    The three errors makes sense because my model right now has three items.



  • First character in QML component must be uppercase.

    See http://doc.qt.nokia.com/4.7-snapshot/qmlreusablecomponents.html#qml-define-components



  • Good catch, thanks. But that doesn't seem to fix anything. I have discovered that adding this in main.cpp (after loading the component) will make it work:

    @
    view->engine()->rootContext()->setContextProperty("DelegateView", DelegateView);
    @

    is that supposed to be necessary? I'm fine with that if it is, just want to make sure that I'm using the API as intended, you know, being thorough and all that other good practice type stuff :-)


Log in to reply
 

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