Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
simon_hain
Posts: 15,846
Registered: ‎07-29-2008
My Device: Z10 LE
My Carrier: O2 Germany
Accepted Solution

Find a dynamically created element from c++

I use ComponentDefinition to create a page.

 

ComponentDefinition {
  id: preferences
objectName: "preferences" Preferences { } }

From c++ i want to find this component, how do I do that?

I tried several approaches with objectName, but none were successful.

- put objectName in the definition (as seen above)

- put objectName in the brackets of Preferences above

- put objectName in the Preferences.qml

 

This is how i try to find the page:

Page* preferences = root->findChild<Page*>("preferences");

 

What i want to achieve is to emit a signal from the dynamically created qml page, connect that to a c++ slot and populate the qml from c++.

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Please use plain text.
Developer
Dredvard
Posts: 160
Registered: ‎01-27-2012
My Device: Playbook
My Carrier: Rogers

Re: Find a dynamically created element from c++

I believe your problem is this:

 

ComponentDefinition only defines the component - the actual instance has to be created by calling createObject function.

 It works successfully for me however objectName needs to be in the Preference page, and can only be accessible once it has been created.

 

I have to take off right now so I can't track down exactly what I did, but here's one way I did it from C++

	Page * slidepage = mNavPane->findChild<Page*>("SlideShowPage");
	if (!slidepage) {
		QmlDocument *slideshowqml = QmlDocument::create(
				"asset:///SlideshowPages/SlideshowPage.qml")
//	    		.parent(this);
		.parent(mNavPane);
		slidepage = slideshowqml->findChild<Page*>("SlideShowPage");
	    mNavPane->insert(2,slidepage);
//		slidepage = mNavPane->findChild<Page*>("SlideShowPage");
		qDebug() << "not slidepage    *****";
	}
	mNavPane->push(slidepage);

 

---
If you find my post helpful please "like" it and "accept as a solution"
Please use plain text.
Regular Contributor
pskarton
Posts: 70
Registered: ‎09-06-2012
My Device: Developer
My Carrier: Bell Mobility

Re: Find a dynamically created element from c++

I connected to basically post the same question but sort of in reverse.  I need to find my QML object in C++. There are similarities so maybe we can resolve both issues.

 

Looked at example which supposedly worked but it was another one of those useless Hello World examples that doesn't work in the "real" world.

 

In included, a signal statement in my QML page and later moved it to my container

                  signal valueChanged(int value)

Added my signal to event

                  onValueChanged {

                            valueChanged(value);

                  }

Created a slot in my c++ object, handleValueChanged, added to list of slots

 

Could not connect signal and slot in c++ object.

 

But, in order to connect I need the container.

 

I think I can find the container if I know the root of the QML document, possibly the page, using findChild<container>

 

In any case, I can't figure out how to save and or pass the "root pointer" created in my app object to an object or QML created later on. Neither, the container nor the object containing the slot exist when my main page is created.

 

Can't find any example of how to save pointers as properties in QML objects, how to reference a container from C++ via objectName or id, and as far as I can tell the parent is not passed to my object when it is created.

                          

Please use plain text.
Developer
simon_hain
Posts: 15,846
Registered: ‎07-29-2008
My Device: Z10 LE
My Carrier: O2 Germany

Re: Find a dynamically created element from c++

Ok, so it seems dynamically created elements are only available after their creation.

 

I have tried another approach and created a Q_INVOKABLE function in my main class (which is propagated to QML using setContextProperty)

I call this function in the onCreationCompleted event of my container:

 Container {
   objectName: "backendContainer"
     onCreationCompleted: {
     console.log("calling populateBackends")                    
     sap.populateBackends()
     console.log("populateBackends called")
   }
}

 In my c++ i have this code:

//invokable
void MyApp::populateBackends() {
  qDebug() << "populateBackends called";
  Container* container = root->findChild<Container*>("backendContainer");
  if (!container) {
  	qDebug() << "backendContainer not found";
  } else {
  	qDebug() << "backendContainer found!!!";
  }
}

 The method is called successfully, but it cannot find the child element.

Debug: calling populateBackends
Debug: populateBackends called
Debug: backendContainer not found
Debug: populateBackends called

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Please use plain text.
BlackBerry Development Advisor
PBernhardt
Posts: 740
Registered: ‎12-16-2008
My Device: BlackBerry Z30
My Carrier: Bell

Re: Find a dynamically created element from c++

Whenever possible, we recommend you structure your app so you do NOT need to use findchild, as it can be slow, doesn't fail very nicely, and makes it difficult to separate the UI from the back end logic.

 

Try to use something like qml->setContextProperty instead, to pass objects into your QML. A lot of our samples (Location Diagnostics, for example) do this.

Paul Bernhardt
Application Development Consultant
BlackBerry
@PBernhardt

Did this answer your question? Please accept this post as the solution.
Found a bug? Report it to the Developer Issue Tracker
Please use plain text.
Regular Contributor
pskarton
Posts: 70
Registered: ‎09-06-2012
My Device: Developer
My Carrier: Bell Mobility

Re: Find a dynamically created element from c++

I don't see in the example _LocationDiagnostics context being used later in C++ objects. I see it used in QML. But we are talking C++ to QML to C++.

 

I think I understand what a context property is in QML but what is it in C++ and how is it referenced.

 

The documentation says " The shared context is accessible via the QmlDocument::documentContext() method." but how is that done if what we are trying to access is the QML document via the context.

Please use plain text.
Developer
simon_hain
Posts: 15,846
Registered: ‎07-29-2008
My Device: Z10 LE
My Carrier: O2 Germany

Re: Find a dynamically created element from c++


PBernhardt wrote:

Whenever possible, we recommend you structure your app so you do NOT need to use findchild, as it can be slow, doesn't fail very nicely, and makes it difficult to separate the UI from the back end logic.

 

Try to use something like qml->setContextProperty instead, to pass objects into your QML. A lot of our samples (Location Diagnostics, for example) do this.


Ok, if this is the recommended approach i'll have a lot of refactoring to do on Monday, as i will have to change ~150 classes to QObject, change the copy uses to pointers, add cleanup of the pointers and make all methods Q_something.

 

I guess I better try it with one class first :Beta1:

 

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Please use plain text.
Developer
Dredvard
Posts: 160
Registered: ‎01-27-2012
My Device: Playbook
My Carrier: Rogers

Re: Find a dynamically created element from c++


PBernhardt wrote:

Whenever possible, we recommend you structure your app so you do NOT need to use findchild, as it can be slow, doesn't fail very nicely, and makes it difficult to separate the UI from the back end logic.

 

Try to use something like qml->setContextProperty instead, to pass objects into your QML. A lot of our samples (Location Diagnostics, for example) do this.


You say not to use findChild and yet in the createLocationSession it uses findChild.  

---
If you find my post helpful please "like" it and "accept as a solution"
Please use plain text.
Developer
simon_hain
Posts: 15,846
Registered: ‎07-29-2008
My Device: Z10 LE
My Carrier: O2 Germany

Re: Find a dynamically created element from c++

I will use the suggested approach, but would still like to get my initial question resolved:
Can i access a dynamically created qml element from c++ using findChild?
----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Please use plain text.
Developer
Dredvard
Posts: 160
Registered: ‎01-27-2012
My Device: Playbook
My Carrier: Rogers

Re: Find a dynamically created element from c++

There's an example in the link they provided;

 

 

In main.qml:

 

https://github.com/blackberry/Cascades-Samples/blob/master/locationdiagnostics/assets/main.qml

 

                onTriggered: {
                    var page = locationPage.createObject()
                    var session = _locationDiagnostics.createLocationSession(true, page)
                    page.session = session
                    navigationPane.push(page)
}
 
 
And then he childFinds from createLocationSession:
 

https://github.com/blackberry/Cascades-Samples/blob/master/locationdiagnostics/src/LocationDiagnosti...

---
If you find my post helpful please "like" it and "accept as a solution"
Please use plain text.