We will have an application with many QML pages. What is the best design approach for navigating pages and sending data from C++ to the QML?
One solution we've talked about is every time a new page is requested it comes back to the C++ code to have the qml loaded for instance using ->setSource(QUrl("qrc:/qml/Main.qml"));
and then a user clicks and we do ->setSource(QUrl("qrc:/qml/Pag1.qml")); etc...
Or is it better to let QML go from page to page using Loader and just setting all the attributes? into the context ahead of time like
Would it be appropriate to load all of the context objects at initialization?
EDIT: please use the @-tags for your code. I added them. gerolf
Navigating between pages using QML has some advantages:
- You can have a so-called "windows stack" that you can go back & forth between views without losing their states and don't have to recreate them.
- You can apply effects when transitioning between views.
Using QDeclarativeView::setSource() to move between views you'll lose the state of the previous view and have to recreate it when coming back.
For context properties, you can set them in advance when the application starts and only access/load the needed data at the right time.
One architecture would be to keep the models in C++ and allow QML to deal with the UI including transitions between windows. "Here":http://doc.qt.nokia.com/4.7/qdeclarativemodels.html#c-data-models is a link to combining C++ models with QML.
I recently developed a multiplatform application running on Windows 7 and Windows CE and faced the same issue.
The best solution is to encapsulate all the "heavy/complex" stuff in QML Items coded in C++ (i.e. derived from QDeclarativeItem ) and eventually some models in C++ as johnk said.
Keeping all the "high level UI logic" in QML you can refactorize it quicker than using C++,
for example you can switch from using qml loader to load one page at a time
to loading all the pages in memory at startup without touching a line of C++.
"Reloading from C++" (i.e. QDeclarativeView::setSource() ) makes sense only when you need to purge all the previously allocated QML data to reclaim memory quickly or when for a reason or another you want to be sure the UI code and data of different pages is clearly separated (i.e. one set of pages is coded by you and the other by the final user for customizations and you want/need to keep 'em separated just in case the final user makes some modifications that may affect your stuff).
Because of the Windows CE requirement (read: a lot less memory available in the Windows CE devices) in my application I added that option too, but exposed the interface to the "C++ loader" on the QML side to let the UI coders decide when they really had to use it and they prefer to avoid it.