eventsonclickqmlblackberry-10

Blackberry 10 click event not trigger when one screen launch on top of other


FirstScreen.hpp 

FirstScreen.cpp 
void FirstScreen:: launchSecondScreen(){
  SecondScreen secondScreen;
}

firstscreen.qml

Page {
    Container {
        Button {
            onClicked: {
                //Launch second screen
              console.log("This will print")
              _app.launchSecondScreen();
            }
        }

    }
}

SecondScreen.hpp 

SecondScreen.cpp 
void SecondScreen:: launchThirdScreen(){
   ThirdScreen thirdScreen;
}

secondscreen.qml

Page {
    Container {
        Button {
            onClicked: {
                //Launch third screen
                console.log("This will not print")
                _app.launchThirdScreen();
            }
        }

    }
}

What happen once I launch second screen on top of first one click event not trigger. Please go through the link for complete project https://github.com/amityadav1984/BB10MultiscreenIssue

Because of that I have to use NavigationPane.


Solution

  • Thanks for providing a Minimal, Complete, and Verifiable example, it really helps to get all the information needed in order to test and replicate.

    First off, let me explain what's happening and then I'll explain how to fix it.

    The reason it's not working :
    You're creating Screen2 object in a method, the object will be deleted at the end of the method. So basically, you're on Screen1, you click on the button which triggers your launchScreen2 method, this method creates a Screen2 object that sets the new visual to Screen2.qml and then the method delete Screen2 object before exiting. When you click on the button on Screen2.qml page, the _app context doesn't exists anymore.

    Why is it working with Screen1 in main.cpp then? Because main.cpp will enter the main event loop before the end of the method, so Screen1 will not be deleted until the main event loop finishes (app exit).

    How to fix :
    1) Create Screen2 as a pointer :

    Screen2* screen2 = new Screen2();
    

    While this will work, be aware that you're responsible for deleting the object when you're done with it, otherwise you'll have memory leaks. A good practice is also to set parent whenever possible, that way you're sure that if the parent is deleted, all children will be too.

    screen2->setParent(this);
    

    Of course, while setting parent is a good practice, an even better practice is to delete any object as soon as they are not needed anymore, keeping your memory footprint as low as possible.

    2) Declare Screen2 as private variable in Screen1.hpp, to make it a global variable.

    Note that by doing so, you need to move the code in Screen2 constructor inside a public method that you'll have to call in Screen1::launchScreen2(), something like screen2.setScene().

    Let me know if you need more information.