Now JavaScript has many advantages: no complicated build process, no architecture limitations, well-known, etc. but QML’s support for it is lacking. Especially the version Sailfish is using.
With that out of the way. I’d like to know how, given a UI element has an objectName defined, I can toggle an attribute on that object and have it work. More specifically:
How can I set busy_rect.visible to true from another component:
I’ve been spending too much time on this and there’s little to be found online (besides “fall back to C++”). As you can see in the code top-level properties can be manipulated. So I’ve also tried tying visible to a property but didn’t succeed.
There was some useful info there and thanks to your comment and a typo I’m starting to think it’s a different issue.
It looks like I can actually access that property without any difficulties but I set visible first to true and then to false in the same onAccepted and apparently UI events do not happen during that time.
If I only set visible to true I see the rectangle appear after the onAccepted is done!
You can also do it the other way around, defining a “global” property in app, and binding that to the visible attribute. This way more than one component can react to the value of that property, and you don’t need to know the id of the child object:
It is important to note that these examples work specifically by using app.foo.
properties defined in the ApplicationWindow are visible to (almost) all other components, because all components are children of app.
In the case of other components, the scope of the id property is different depending on where these objects have been defined.
E.g. here, dialog_a can not “see” the properties of dialog_b
As you may have seen, i don’t use objectName at all. I had no idea it existed.
Instead i assign the accepted action in the enclosing component.
Or more specifically, connect that signal(?) to a a function defined there, like this:
Though i really have no formal understanding of how scoping is supposed to work - i have been told that similar things shouldn’t actually work.
Sometimes i have resorted to defining a random signal somewhere way up in the ApplicationWindow and triggering (on) that.
One more thing to note is that assigning a property through JavaScript destroys any binding that property may have.
E.g.:
Rectangle { id: rect
property bool colored: true
color: colored ? "blue" : "transparent"
}
Button {
onClicked: rect.colored = !rect.colored // toggles blue and transparent
}
Button {
onClicked: rect.color = "red" // makes it red but removes the binding to "colored"
}
@attah I just figured out I’m getting at the attributes through the object’s id, something I also thought was not possible but perhaps because I’ve declared this specific components at the top level it’s no issue (For my previous version in Common Lisp (which used C++ wrappers) I did very much need objectName.)
@nephros Thanks for the info on scoping and bindings. It’s pretty all confusing. edit: ah your initial reply has way more info, I missed that initially for some reason!
It is a pity the QML / QT access from JS is still pretty limited. At least in the QT version we’re using. One would think easily getting at another object would be one of the first things to be supported.
There are actually a lot of ways you can create and interact with QT objects in JS. I’m no expert, but a number of methods can be seen in tooter:
and look at how those ListModel objects are used in Main.qml and the ‘MyList.qml’ component.
Using notifications, signals and QtObjets you can do anything you want, but you have to get your head around the model. Which I need to redo every quarter :0