Reputation: 19075
I used to have this arrangement of a window with one text field in it, updated with data emitted from c++ :
Window{
id: root
function qmlSlot(a){
_textField1.text=a;
}
TextField{
id: _textField1
}
}
The binding is like this:
QQuickWindow *window=qobject_cast<QQuickWindow*>(topLevel);
QObject::connect(src,SIGNAL(someSignal(QVariant)),window,SLOT(qmlSlot(QVariant)));
Now I added more things (tabs) to the main window and things don't work straightforwardly anymore.
A: When I leave qmlSlot
in the Window scope, it does not see _textField1
:
Window{
id: root
function qmlSlot(a){
_textField1.text=a;
}
TabView{
Tab{
TextField{
id: _textField1
}
}
}
}
which gives me:
qrc:/main.qml:32: ReferenceError: _textField1 is not defined
B: When I move the slot itself to the scope of _textField1
, I don't know how to bind to it from c++:
Window{
id: root
TabView{
Tab{
function qmlSlot(a){
_textField1.text=a;
}
TextField{
id: _textField1
}
}
}
}
resulting in:
QObject::connect: No such slot QQuickWindowQmlImpl_QML_21::qmlSlot(QVariant)
How can I have qmlSlot
called from c++ while accessing nested items (_textField
in this case)? Is it possible to make it such that I don't have to change the binding code when I decide to change the window layout?
Upvotes: 2
Views: 1486
Reputation: 7150
Your problem is that Tab
is in fact a Loader
, so it means that your TextField is created on demand and in another context. When your Tab
isn't active there is no TextField
to access.
You could access your textfield with tab.item
, but it would only work when the tab is loaded.
You have a deeper problem though, accessing QML objects from c++ is bad practice as that means that your business layer has to be aware of your UI layer. That's not good if you want to refactor your UI. What you should do instead is pull data from c++ in your QML. More explanation here : Interacting with QML from C++.
In your case, I would create a QObject
subclass with a property or a signal (is it a state of your object or an event?).
Then use setContextProperty
to make one of your object instance available to the QML engine.
And in your QML you'd just do (if it's a property):
Window{
id: root
TabView{
Tab{
TextField{
text: myCppObject.textProperty
}
}
}
}
Upvotes: 2
Reputation: 13421
I've never used QML before but the docs suggest that you need to assign a value to each object's id
property so that you can refer to it. I think the following should work (but have not tested it).
Window{
id: root
function qmlSlot(a){
mytabview.mytab._textField1.text=a;
}
TabView{
id: mytabview
Tab{
id: mytab
TextField{
id: _textField1
}
}
}
}
Upvotes: -1