NavigationPane - why is this going to work?

I'm frustrated by NavigationPane do not behave as I would expect when you press the pages of recursively. I have three files QML. MyNavPane.qml, MyFirstPage.qml, and MySecondPage.qml, and suppose that MyFirstPage.qml looks like this:

Page {
   property NavigationPane mainNavPane
   attachedObjects: [
      MySecondPage {
         id: mySecondPage      }
   ]
   function pushSecondPage() {
      mainNavPane.push( mySecondPage );
   }
}

.. .While that MyNavPane.qml is as follows:

NavigationPane {
   id: myNavPane
   attachedObjects: [
      MyFirstPage {
         id: myFirstPage
         mainNavPane: myNavPane
      }
   ]
   function pushFirstPage() {
      push( myFirstPage );
   }
}

Now the execution of pushFirstPage() works fine and pushes the first page in the navigation stack, however, pushSecondPage() runs without error, but the second page is not pressed. Debugging indicates that mainNavPane correctly to the main NavigationPane.

If I change MyFirstPage.qml to this:

Page {
   property NavigationPane mainNavPane
   function pushSecondPage() {
      mainNavPane.pushSecondPage();
   }
}

... and MyNavPane.qml to this:

NavigationPane {
   id: myNavPane
   attachedObjects: [
      MyFirstPage {
         id: myFirstPage
         mainNavPane: myNavPane
      },
      MySecondPage {
         id: mySecondPage
      }
   ]
   function pushFirstPage() {
      push( myFirstPage );
   }
   function pushSecondPage() {
      push( mySecondPage );
   }
}

... it works as expected.

I tried to do that too, but that didn't work either, the second page has not pushed, but no error was reported:

Page {
   property NavigationPane mainNavPane
   attachedObjects: [
      MySecondPage {
         id: mySecondPage
      }
   ]
   function pushSecondPage() {
      mainNavPane.pushPage( mySecondPage );
   }
}

NavigationPane {
   id: myNavPane
   attachedObjects: [
      MyFirstPage {
         id: myFirstPage
         mainNavPane: myNavPane
      }
   ]
   function pushFirstPage() {
      push( myFirstPage );
   }
   function pushPage( page ) {
      push( page );
   }
}

Why only the second method, where the two sheets to be pushed to the NavigationPane itself works, while the other two don't? What Miss me?

UPDATE: I decided that I needed to know if change the parent of the page to be pushed would work, and it does!

The first thing I had to do was make a way to change the parent of a QML object, which you can not do normally. I created a new function Q_INVOKABLE on my main user interface class, called changeParent():

void MyApp::changeParent( QObject* object, QObject* newParent ) {
   object->setParent( newParent );
}

Then, I changed the function pushPage() in one of my previous examples:

Page {
   property NavigationPane mainNavPane
   attachedObjects: [
      MySecondPage {
         id: mySecondPage
      }
   ]
   function pushSecondPage() {
      mainNavPane.pushPage( mySecondPage );
   }
}

NavigationPane {
   id: myNavPane
   attachedObjects: [
      MyFirstPage {
         id: myFirstPage
         mainNavPane: myNavPane
      }
   ]
   function pushFirstPage() {
      push( myFirstPage );
   }
   function pushPage( page ) {
      app.changeParent( page, myNavPane )
      push( page );
   }
}

... and now the page pushes perfectly, even though he did not initially belong to the NavigationPane. I also tried to change the parent to zero and that works too, but I felt more comfortable never leave the page hanging out without a parent. Memory leaks can be insidious.

I also tried to change the parent in creationCompleted Manager, but that properly compiled it screwed up of access to the MySecondPage object in other code. Since mainNavPane have a value during execution of the creationCompleted Manager, QML am confused and thought that mySecondPage no longer exists when I put this code:

Page {
   property NavigationPane mainNavPane
   attachedObjects: [
      MySecondPage {
         id: mySecondPage
         onCreationCompleted: {
            app.changeParent( mySecondPage, mainNavPane )
         }
      }
   ]
   function pushSecondPage() {
      mainNavPane.pushPage( mySecondPage );
   }
}

Change this to set the new parent to zero instead of mainNavPane works but is dangerous since mySecondPage will be orphaned until you call pushSecondPage at least once. If you run never push that will leave you mySecondPage when you destroy What's new, which is a memory leak.

Of course, you can do it instead:

Page {
   property NavigationPane mainNavPane
   attachedObjects: [
      MySecondPage {
         id: mySecondPage
      }
   ]
   onMainNavPaneChanged: {
      app.changeParent( mySecondPage, mainNavPane )
   }
   function pushSecondPage() {
      mainNavPane.pushPage( mySecondPage );
   }
}

in this case you need not change the parent again whenever you press the page, probably a better solution.

Anyway, thanks again for pointing me in the right direction and I hope that it will be useful to others.

Tags: BlackBerry Developers

Similar Questions

Maybe you are looking for