Any way to retrieve staff characteristics?
After exhausting everything I could think of - does anyone know if the below is possible; and if so, how?
For a plugin I am working on, I need to be able to determine which staves are standard notation, which are tabs; and what their instruments (or part names) are - or some way to match up which staves belong to which parts. And this would generally be in multi-part arrangements.
There appear to be a number of properties in the 'Element' object which should enable me to do this (when combined with iterating over all the parts and staves in a loop). For example, element.staffLines, element.staffGenClef, etc. However, everthing I've tried to date returns only "undefined" for these properties. Am I missing something with respect to retrieving those properties? Or have some of these not yet been implemented perhaps?
Any help on this would be appreciated.
My console output in attempting to read the Element attributes from Chord, Measure and System elements:
Debug: Running....
Debug: Root e type: Chord | at tick: 480
Debug: --| staffLines: undefined
Debug: --| hasPitchedStaff: undefined
Debug: --| instrumentId: undefined
Debug: --| timesigNominal: 0 / 1
Debug: --| actualNotes: undefined
Debug: --| measureNumberMode: undefined
Debug: --| role: undefined
Debug: --| track: 0
Debug: --| fretStrings: undefined
Debug: --| staffGenClef: undefined
Debug: =====
Debug: Root e's parent: Segment | at tick: 480
Debug: ----| staffLines: undefined
Debug: ----| hasPitchedStaff: undefined
Debug: ----| instrumentId: undefined
Debug: ----| actualNotes: undefined
Debug: ----| measureNumberMode: undefined
Debug: ----| role: undefined
Debug: ----| track: -1
Debug: ----| fretStrings: undefined
Debug: ----| staffGenClef: undefined
Debug: =====
Debug: Root e's parent.parent: Measure | at tick: 480
Debug: ------| staffLines: undefined
Debug: ------| hasPitchedStaff: undefined
Debug: ------| instrumentId: undefined
Debug: ------| timesigNominal: 4 / 4
Debug: ------| actualNotes: undefined
Debug: ------| measureNumberMode: 0
Debug: ------| role: undefined
Debug: ------| track: -1
Debug: ------| fretStrings: undefined
Debug: ------| staffGenClef: undefined
Debug: =====
Debug: Root e's parent.parent.parent: System | at tick: 480
Debug: --------| staffLines: undefined
Debug: --------| hasPitchedStaff: undefined
Debug: --------| instrumentId: undefined
Debug: --------| actualNotes: undefined
Debug: --------| measureNumberMode: undefined
Debug: --------| role: undefined
Debug: --------| track: -1
Debug: --------| fretStrings: undefined
Debug: --------| staffGenClef: undefined
[For context: I am trying to create a plugin that will generate non-standard fretted tabulature using the notation on one of the standard staffs. I need a way for both the user, and my code, to unambigiously specify the "input" and "output" staves for the operation - again, in a multi-part score with mixed-and-matched instruments.]
Attachment | Size |
---|---|
jeffForStudy_ElementLister.qml | 4.69 KB |
Comments
Element is a generic class, covering properties for all different kind of subtypes; which will only be populated for an element of that relevant subtype.
https://musescore.github.io/MuseScore_PluginAPI_Docs/plugins/html/class…
Try working from "
curScore.parts
" to identify instruments/staves themselves. I don't know how much staff information can be found that way, but instrument information at least is.In reply to Element is a generic class,… by jeetee
Thanks for responding jeetee. I did try to work with 'parts,' but I can't figure out any way to get just the staves that are members of a specific part. There is a bool property that will tell me if there is a standard and/or TAB staff, but I can't find a way to get their staff index values. And even if I can get them, I can't see how I'd determine which is standard and which one is the TAB given that I can't seem to get any object I can reference to return those element. staff... properties.
Maybe another approach to this question is: Could anyone show me some plugin code that references an object which does return a value for those 'staff' properties. E.g., returns a value for, say, element.staffGenClef.
(To me, as an old data-modeller, I keep expecting the equivalent of a foreign-key from a 'staff' object back to the 'part' object it belongs to. But the exposed class hierarchy in the plugin API doesn't seem to be modelled that way. Seems like it's been really flattened via the Element class. Which is fine...if only I could work out how to reference the right objects/classes to return those pesky staff properties that are listed as being available in the Element class.)
Am still trying to figure this out. I am not a C++ or Qt code expert; but have been trying to study the musescore source to see if I can work out a solution. I do see that in element.cpp there is an element type of "STAFF" [in Element* Element::create(ElementType type, Score* score) -- case ElementType::STAFF:].
But I still cannot figure out how to reference any such element in QML. If anyone knows, please help.
In reply to Am still trying to figure… by rocchio
AFAIK this element is not directly exposed in the plugin API; which is why I hinted at looking into the parts (which == the instruments in the score in this case). There are 4 tracks per staff, so that should get you somewhere.
In reply to AFAIK this element is not… by jeetee
OK. Just to be clear - you are saying that, at present, there is no way to retrieve the value of the staffGenClef property of the element object from with QML. Meaning that it has been, in effect, 'hard coded' to simply return "undefined" back to QML no matter the context. Do I have this right?
I'll go ahead and explore more down your suggested path.
In reply to OK. Just to be clear - you… by rocchio
Quite the contrary in fact.
I'm saying that you can request the
staffGenClef
from any element using QML. But that for element types that don't have that property internally, undefined will be returned.Now a look at the plugin API learns that this property is linked to the c++ property defined as
Ms::Pid::STAFF_GEN_CLEF
which in turn is only defined for aStaffTypeChange
element.So if you want that value in QML to be anything else than undefined, then make sure you're calling it on an element of the type
Element.STAFFTYPE_CHANGE
In reply to AFAIK this element is not… by jeetee
By looking into the source to explain that property to you, I came to realize that since 3.5.0, the Staff element now should be available to the Plugin API.
See this commit for when it was added. This change view also shows you should be able to call
staff()
on an element to get its staff object.In reply to By looking into the source… by jeetee
After several hours working on this, it's still quite frustrating. Some partial success tho, which will probably be close enough for my needs. Tho it is still troublesome that I cannot work out what's going on.
Your response did enable me to obtain the Staff object using
var staff = element.staff;
In addition I am able to get the staffs for a part by usingstaff.part.partName;
. So this will allow me to at least match up staffs to parts. However, the element.staff object still only returns 'undefined' for those 'staff...' element properties showing in the QML documentation. Looking at the pull request you pointed me to I was able to prove that the element.staff object in QML does return the properties defined for the class Staff object that is defined in elements.cpp. Tho, sadly, those properties aren't the ones I need.So I will try to let this go now and move on with my plugin. The silver lining is that this has begun to pull me into the journey of understanding Qt - which I've no prior knowledge of. I spent time delving into the Q_Property construct and feel I do at least understand what's going on there. As to the rest of it; and exposing the backend code out to QML...I don't yet have a clue to how that works and am thus unable, yet, to work out these puzzles on my own.
Thanks for your help jeetee.
In reply to After several hours working… by rocchio
As mentioned before, those properties only exist for "Staff Type Change" elements, not for staves themselves (not even internally).
So another question would be what you were hoping to find there..
In reply to As mentioned before, those… by jeetee
Gotcha. My need is to be able to identify which staff, if any, is the TAB staff. Am trying to make a plugin which generates a non-standard fretted TAB for the diatonic Mountain Dulcimer given a standard notation staff for the same part.
So at this point I will assume that the TAB staff in the part is always the 2nd staff in that part - when 'counting' by staffindex. So I figure I now know: how to present the user with a list of all parts that have 2 staffs, and have them select which of those parts they want to populate the TAB for. I will need to provide some text to inform them that the 3-string TAB staff must already have been added to the part, and that they need to be sure they don't select a non-TAB 2-staff part (e.g., piano).
In reply to Gotcha. My need is to be… by rocchio
I think that identification (and/or setting number of staff lines) is currently indeed not quite possible using the plugin framework.
Opting for telling your users the expected begin situation (namely, creating that staff, perhaps with instruction on how to do so) seems the sensible way forward.
That and then opening an issue in the issue tracker to include that functionality into the plugin framework in a future version.
In reply to I think that identification … by jeetee
Yep. I just posted issue Make Complete Set of Staff Properties Available to the QML Plugin API
In reply to Yep. I just posted issue… by rocchio
Or #311093: Make Complete Set of Staff Properties Available to the QML Plugin API