PDA

View Full Version : objectName property doesn't work as expected in C++ defined QML classes



nuliknol
31st October 2016, 23:58
I have a custom QML type which I register like this in main.cpp:


qmlRegisterType<Gate>("client_gate",1,0,"Gate");

Then in main.qml I declare it like this:


Gate {
id: client_gate
objectName: "oo"
}

The problem is I can't find it with my C++ code in main.cpp after QML engine is loaded:



QObject *root = engine.rootObjects()[0];
QObject *o;
o=root->findChild<QObject*>("oo");
if (!o) return 1;
Gate *g;
g=(Gate*) o;
g->set_Client(&client);

I know the code works, because I can find objects of standard QML type (like SwipeView for example) but it doesn't work with my own QML (C++) classes , findChild() just returns null. Why is this happening?
Do I have to define "objectName" property in "Gate" c++ class too ? Isn't it supposed that QObject already has "objectName" property ?

Any help will be greately appreciated.
TIA

nuliknol
1st November 2016, 02:56
Why is this happening?

I commented out all the QML objects except my custom C++ class called "Gate" and ran this code:


QList<QObject *> list = root -> findChildren<QObject *> ();

qWarning() << "list size is " << list.size();
for(int i=0;i<list.size();i++) {
qWarning() << "i="<<i<<", "<< list.at(i) << " name="<<list.at(i)->objectName();
}

and I have got this output:

list size is 0

So aparently my custom C++ object is not included in the children's list, but I do have it in main.qml:



Gate {
objectName: "oo"
id: client_gate
}

Very weird stuff.

anda_skoa
1st November 2016, 09:46
Is your "Gate" element the top element itself? I.e. it is "root"?

In any case, you probably don't need that at all, it is very uncommon to access QML instantiated objects like that.

Cheers,
_

nuliknol
1st November 2016, 15:29
Is your "Gate" element the top element itself? I.e. it is "root"?

In any case, you probably don't need that at all, it is very uncommon to access QML instantiated objects like that.

Cheers,
_
No, it is not root, it is a child of the ApplicationWindow. I wonder why it is uncommon. If you have some objects in main.cpp how do you link objects in QML to those that are located in main.cpp at application startup from main.cpp itself ?

anda_skoa
1st November 2016, 18:00
No, it is not root, it is a child of the ApplicationWindow.

Hmm. Have you tried with something else than a ApplicationWindow?
Or having the Gate inside an Item in the window?



I wonder why it is uncommon.

Because you usually will want to avoid a C++ -> QML dependency. i.e. making the more static C++ side depend on the more dynamic QML side.
This kind of dependency restricts what you can do QML side.



If you have some objects in main.cpp how do you link objects in QML to those that are located in main.cpp at application startup from main.cpp itself ?
By exposing C++ API to QML instead.

Cheers,
_

nuliknol
17th November 2016, 18:05
I think I found the answer to why the object was not found by root->findChild<QObject*> call. I think it wasn't found because my type (I have registered with qmlRegisterType) is not an Item-derived object.

anda_skoa
18th November 2016, 09:38
I think I found the answer to why the object was not found by root->findChild<QObject*> call. I think it wasn't found because my type (I have registered with qmlRegisterType) is not an Item-derived object.

Right, objects instantiated in QML might not have the QObject parent one thinks they have.
Another very good reason not to try findChild() or findChildren() on a QML object tree in the first place.

Aside from being an unnecessary hack it is also an unreliable hack.

Cheers,
_