11-09-2012 07:58 AM
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++.
Solved! Go to Solution.
11-09-2012 08:57 AM
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);
11-09-2012 09:28 AM
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.
11-09-2012 09:31 AM
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
11-09-2012 02:23 PM
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.
11-09-2012 04:50 PM
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.
11-09-2012 05:33 PM
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 ![]()
11-09-2012 07:13 PM
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.
11-12-2012 03:58 AM
11-12-2012 08:53 AM
There's an example in the link they provided;
In main.qml:
https://github.com/blackberry/Cascades-Samples/blo