TypeError: Cannot assign to read-only property "parent"

• May 5, 2021 - 23:50
Reported version
S4 - Minor
by design

363:-1: TypeError: Cannot assign to read-only property "parent"
Warning: file:///C:/Users/tglase/Documents/MuseScore3/Plugins/count-note-beats.qml:363: TypeError: Cannot assign to read-only property "parent"

The code in question is:

       var text = newElement(Element.STAFF_TEXT);
        text.parent = cursor.element;

This works in Debian’s (patched) 3.2.3 but not in OS: Windows 10 (10.0), Arch.: x86_64, MuseScore version (64-bit):, revision: 3224f34.

Cross-reference: https://musescore.com/groups/musescore-cafe/discuss/5076457


I would say this is by design and should work that way. The property parent has been introduced to the plugin API in MuseScore 3.3 (see its documentation), and it is indeed read-only. This code works in 3.2.3 version simply because JavaScript (which is what QML is based on) allows assigning any values to non-existing properties of any object (which just adds that property to the object), and QML engine doesn't enforce anything on top of that since parent property does not exist in that version of the plugin API.

oic, but how are you supposed to add a new element to a note then?

It might be worth noting that this is a patched 3.2.3 with about a hundred backports, mostly bugfixes, from later version. It contains commit f1369d3a5ae1beca7a01fd06719ffe93f39cfb47 “Plugins: fix a crash on getting element's parent if parent is null” as patch, so perhaps the parent property already existed in 3.2 but the since-version was later increased because it changed somehow? Like score.staves? (Or maybe I also backported that but didn’t remember it.) Either way, this must have worked at some point in time, before it became read-only.

Logically, parent must be assignabe anyway, otherwise newElement() would be of no use since all elements must have a parent in order to work…

If we look at the code…

if (cursor.element.type !== Element.CHORD)
var text = newElement(Element.STAFF_TEXT);
text.parent = cursor.element;
text.text = "something";
text.placement = Placement.ABOVE;

… ah, does the cursor.add(newly-created-element) set its parent to cursor.element automatically then? file:///usr/share/mscore3-3.2/manual/plugins/html/class_ms_1_1_plugin_a_p_i_1_1_cursor.html#ad648841187c29afcf273a4037d2cb4ba is not clear about this, it simply says “Adds the given element to a score at this cursor's position.” but nothing about what will become its parent (i.e. the “position”, the “where in the score”, is defined, but not the “where in the element instance hierarchy”).

Yes, cursor.add() assigns a parent to the added element, and chooses that parent based on the added element's type. For example, a staff text should be added to a segment in the internal score hierarchy, and cursor.add() handles that automatically. Cursor does not operate on individual note level though so in order to add an element to an individual note you should call note.add(element) for that note.

Concerning the commit you have mentioned, it has indeed been added to fix an issue which came up in that parent property but the fix itself is pretty generic and does not require parent property to be in place. So this fix can certainly be applied to earlier versions of MuseScore.