How to for plugin development
Updated 5 years ago
This documentation applies to plugins for 1.x only!
Documentation for 2.x+ is built into the Plugin Creator of Musescore.
( ⇒ In Musescore press Ctrl+Shift+P, then F1 to bring it up. )
Click here for Documentation for 3.x
A list of useful snippets for plugin creation.
Applying a function to each note of a selection
// Apply the given function to all notes in selection
// or, if nothing is selected, in the entire score
function applyToNotesInSelection(func) {
if (typeof curScore === 'undefined')
return;
var cursor = new Cursor(curScore);
cursor.goToSelectionStart();
var startStaff = cursor.staff;
cursor.goToSelectionEnd();
var endStaff = cursor.staff;
var endTick = cursor.tick() // if no selection, end of score
if (cursor.eos()) { // no selection
startStaff = 0; // start with 1st staff
endStaff = curScore.staves; // and end with last
}
for (var staff = startStaff; staff < endStaff; ++staff) {
for (var voice = 0; voice < 4; voice++) {
cursor.goToSelectionStart(); // sets voice to 0
cursor.voice = voice; //voice has to be set after goTo
cursor.staff = staff;
if (cursor.eos())
cursor.rewind() // if no selection, beginning of score
while (cursor.tick() < endTick) {
if (cursor.isChord()) {
var chord = cursor.chord();
var n = chord.notes;
for (var i = 0; i < n; i++) {
var note = chord.note(i);
func(note);
}
}
cursor.next();
}
}
}
}Calling an external process or a command line tool
Lilypond is called in this example. A plugin could also save as MusicXML, manipulate the MusicXML file and open it again via Score.load()
//---------------------------------------------------------
// init
// this function will be called on startup of mscore
//---------------------------------------------------------
function init()
{
}
//-------------------------------------------------------------------
// run
// this function will be called when activating the
// plugin menu entry
//-------------------------------------------------------------------
function run()
{
// temp folder for user C:\Users\<USERNAME>\AppData\Local\Temp on windows
var path = QDir.tempPath(); //
var file = path + "/score.ly";
curScore.save(file, "ly");
//See http://doc.qt.nokia.com/latest/qprocess.html
var lilypond = new QProcess();
var args = new Array();
args[0]= "-o";
args[1]= path;
args[2]= file;
// if you want to log output
//lilypond.setStandardOutputFile("stdout.txt");
//lilypond.setStandardErrorFile("stderr.txt");
lilypond.start("lilypond", args );
lilypond.waitForStarted();
lilypond.waitForFinished();
}
//---------------------------------------------------------
// menu: defines were the function will be placed
// in the MuseScore menu structure
//---------------------------------------------------------
var mscorePlugin = {
menu: 'Plugins.Lilypond process',
init: init,
run: run
};
mscorePlugin;
Creating a GUI using Qt
You can access almost any class of the Qt Framework from the plugin framework
The easiest way to make a dialog or UI is to use Qt Creator. Qt Creator is installed with your version of Qt.
- Open Qt Creator
- File -> New File or Project -> Qt -> Qt Designer Form
- Create your form with the graphic interface. You may want to learn more about Layout Management in Qt
- Save your file as for example
my.ui - In your script use the following lines
//read the UI file and create a form out of it var loader = new QUiLoader(null); var file = new QFile(pluginPath + "/my.ui"); file.open(QIODevice.OpenMode(QIODevice.ReadOnly, QIODevice.Text)); form = loader.load(file, null); //initialize some widget value if necessary form.verticalLayoutWidget.myLabel.text = curScore.title; form.verticalLayoutWidget.myLabel2.text = curScore.composer; //connect signal form.searchBtn.clicked.connect(doSomething); form.closeBtn.clicked.connect(close); //show the form form.show();
- Signals and slots are a Qt concept. When a signal is fired (for example with a button is clicked), slots connected to it are executed. Slots can be define in your script to do something when something happens in the interface