I've got a QML mobile app based around a StackView. Anytime I push a new screen onto the stack I notify a C++ function that the screen is about to load and load the appropriate controller (C++ class which manages the data and other tasks related to this view).

So to load the controllers I have the following on the QML side:

Qt Code:
  1. function createScreenObject(path, props) {
  2. // notify the backend that we are about to create a screen.
  3. shellinterface.initScreen(path)
  4. var component, obj
  5. component = Qt.createComponent(Qt.resolvedUrl(path))
  6. if (component.status === Component.Ready) {
  7. obj = component.createObject()
  8. obj.screenName = path
  9. }
  10. else if (component.status === Component.Error)
  11. shellinterface.logError("Screen::createScreenObject(" + path + ")" + " - Error loading component: " + component.errorString())
  12. return {item:obj, properties:props, destroyOnPop:true}
  13. }
  14.  
  15. stack.push(createScreenObject("To-Do Module/TasksToDoView.qml"))
To copy to clipboard, switch view to plain text mode 

Then in the C++ backend I have the initScreen function which is similar to:

Qt Code:
  1. void ShellInterface::initScreen(const QString &identifier) {
  2. if (identifier.endsWith("ContextView.qml")) {
  3. loadController<ContextController>(identifier);
  4.  
  5. }
  6. else if (identifier.endsWith("EmployersView.qml") || identifier.endsWith("AddEditEmployerView.qml"))
  7. loadController<EmployersController>(identifier);
  8. }
To copy to clipboard, switch view to plain text mode 

So for each view I can load any number of controllers. This works great, because the controllers are loaded before the QML, so the QML can safely use the controller functions when it loads.

The problem comes when unloading. Currently all the screens that get loaded onto the StackView are derived from a Screen object. To unload the controller, I have something like:

Qt Code:
  1. Screen.qml
  2. Rectangle {
  3. property string screenName
  4. Component.onDestruction: shellinterface.deinitScreen(screenName)
  5. }
To copy to clipboard, switch view to plain text mode 

This works, except that onDestruction is called before the component is fully done being destroyed. So when I unload the controller I get errors from QML bindings that are still trying to read values from the controller.

How would I change it from onDestruction to something like onDestroyed? I want to run code after the QML item is totally gone, but I can't see any events I could hook up to.
Thoughts?