MuseScore Documentation

MuseScore is an open source and free music notation software. For support, contribution, bug reports, visit MuseScore.org. Fork and make pull requests!

15,254 stars C++ C++ 13 files ยท ~8,893 tokens #cpp#musescore#music-notation#musicxml#qt#sfz#sheet-music#sheetmusic
RAW Doc

Technical Documentation: musescore/MuseScore

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

Overview (README.md)

Music notation and composition software


MuseScore Studio is an open source and free music notation software. For support, contribution, and bug reports visit MuseScore.org. Fork and make pull requests!

Features

  • WYSIWYG design, notes are entered on a "virtual notepaper"
  • TrueType font(s) for printing & display allows for high quality scaling to all sizes
  • Easy & fast note entry
  • Many editing functions
  • MusicXML import/export
  • MIDI (SMF) import/export
  • MEI import/export
  • MuseData import
  • MIDI input for note entry
  • Integrated sequencer and software synthesizer to play the score
  • Print or create PDF files

More info

License

MuseScore Studio is licensed under GPL version 3.0. See license file in the same directory.

Packages

See Code Structure on Wiki

Building

Read the Compilation section of the MuseScore Wiki for a complete build walkthrough and a list of dependencies.

Getting sources

If using git to download repo of entire code history, type:

text
git clone  --recurse-submodules https://github.com/musescore/MuseScore.git
cd MuseScore

(The --recurse-submodules ensures that the muse_framework git submodule is checked out into the muse/ subdirectory.)

Otherwise, you can just download the latest source release tarball from the Releases page, and then from your download directory type:

text
tar xzf MuseScore-x.x.x.tar.gz
cd MuseScore-x.x.x

Release Build

To compile MuseScore Studio for release, type:

text
cmake -P build.cmake -DCMAKE_BUILD_TYPE=Release

On MacOS, append -G Ninja in order to use the ninja build tool (which you may need to install), since this
is required to compile Swift components.

If something goes wrong, append the word "clean" to the above command to delete the build subdirectory:

text
cmake -P build.cmake -DCMAKE_BUILD_TYPE=Release clean

Then try running the first command again.

Running

To start MuseScore Studio, type:

text
cmake -P build.cmake -DCMAKE_BUILD_TYPE=Release run

Or run the compiled executable directly.

Debug Build

A debug version can be built and run by replacing -DCMAKE_BUILD_TYPE=Release
with -DCMAKE_BUILD_TYPE=Debug in the above commands.

If you omit the -DCMAKE_BUILD_TYPE option entirely then RelWithDebInfo is
used by default, as it provides a useful compromise between Release and Debug.

Testing

See the Unit tests section of the MuseScore Studio Wiki for instructions on how to run the test suite.

Code Formatting

Run ./hooks/install.sh to install a pre-commit hook that will format your staged files. Requires that you install uncrustify.

If you have problems, please report them. To uninstall, run ./hooks/uninstall.sh.


README (`docs/README.md`)

We use the jsdoc tool to create API documentation.

What does the documentation consist of:

  • Static documentation - here is a tutorial and description of classes
  • Description of API methods - located in the API implementation files.
  • Snapshots - here is the generated documentation for each version.
  • index.html - this is the entry point for https://musescore.github.io
  • Tools for generation - here you will find a documentation extractor for API methods, a documentation generator (jsdoc) and automation scripts.
  • Generation and update process - see description below

Static documentation

location: docs/apidocs_static

This is where static documentation is stored in the jsdoc format.

Description of API

Descriptions of API methods are located in .cpp,.h files where the implementation of the methods is located.
The description is in jsdoc format (see https://jsdoc.app), but the first line should indicate that this is APIDOC documentation.

Namesapces

Like api.log., api.interactive....

text
/** APIDOC
 * Write messages to log and console
 * @namespace log
 */
LogApi::LogApi(api::IApiEngine* e)
    : ApiObject(e)
{
}

There must be the @namespace tag with the namespace name

Classes (types)

text
/** APIDOC
 * Class representing a lyric.
 * @class Lyric
 * @hideconstructor
*/
class Lyric : public EngravingItem
{
    ...

There must be the @class tag with the class name
If the type cannot be created in js using the new operator,
then we need to add the @hideconstructor tag

Methods

text
/** APIDOC
 * Show information message
 * @method
 * @param {String} title Title
 * @param {String} text Message
 */
 void InteractiveApi::info(const QString& contentTitle, const QString& text)
{

There must be the @method tag

Properties

text
/** APIDOC @property {number} - count of lyrics */
int Score::lyricCount() const

There must be the @property tag, the description should be in one line

Enums

text
/** APIDOC
     * Question buttons
     * @enum
     */
    enum Button {
        ...
    };

There must be the @enum tag

When generating documentation, we first extract this documentation from the cpp files.

Snapshots

location: snapshots

To be able to view the documentation for each version, we generate snapshots of the documentation for each version and place them in the appropriate folder, for example: snapshots/4.5, snapshots/4.6

index.html

location: index.html - this is the entry point for https://musescore.github.io

After generating a snapshot for a new version, we need to add a link to it in this index.html, like others.

Tools for generation

location: tools/jsdoc

List of tools:

  • template - template for jsdoc
  • jsdoc_extractor.js - this is a documentation extractor from cpp files. It extracts documentation and stores it in temporary, fake js files so that jsdoc can process them.
  • conf.json - file of configuration for jsdoc
  • jsdoc_install.sh - script of jsdoc install
  • jsdoc_run.sh - script for executing the generation process

This tool requires node.js and npm to be installed to work. To run scripts on Windows, use GitBash.

The generated documentation is placed in a temporary dir gen_apidoc.

Generation and update process

When developing a new version of an application, adding new APIs or changing current ones, or for those that don't have documentation, we need to write documentation, just like any other change in the repository.

After releasing a new version of the application, we need to generate a snapshot of the API documentation for it.

Process:

  1. Install node.js and npm
  2. Run bash ./tools/jsdoc/jsdoc_install.sh
  3. Run bash ./tools/jsdoc/jsdoc_run.sh
  4. Look the result, open it in browser index.html from ./tools/jsdoc/gen_apidoc/
  5. Clone musescore.github.io
  6. Copy dir ./tools/jsdoc/gen_apidoc/ to musescore.github.io/snapshots/x.x
  7. Add a link to the new version in musescore.github.io/index.html

Apidocs Static Home (`docs/apidocs_static/Home.md`)

Extensions

Extensions are a way to extend the basic functionality and add new features to the application.

The application has built-in extensions, we can find them at Home - Plugins. We can also install third-party extensions.

Before the extension will work, we need to enable it. This can be done at Home - Plugins. Enabled extensions will be available for calling from the Menu - Plugins.

Development

Now we have two types of extensions:

  • forms are extensions that have a user interface through which we can control the extension logic.
  • macros are extensions without a user interface, having only a script that performs some actions (usually some kind of automation)

There is also a special type - composite. This is an extension that can consist of several forms, or a form and macros.

Each extension consists of a {@tutorial 2_manifest} file that describes the extension - its identifier, type, title, icon, scripts, config and etc.
Qml is used to create {@tutorial 3_form} user interfaces, and javascript is used to write {@tutorial 4_macros} scripts. Api is provided to access the application, and API UI is provided UI controls.

See {@tutorial 1_getting_started}

Documentation

How this documentation is created, see docs/README.md


Old Docs I18n (`docs/old_docs/i18n.md`)

\page i18n Internationalization

This page gives an overview of options on how to translate a plugin to different languages.

Reuse MuseScore translatable strings

If your plugin only needs strings that are already used within MuseScore (e.g. some musical terms or actions names) the simplest method to keep a plugin translated is to reuse translations that already exist in MuseScore. In order to do this you need to use qsTranslate() function with appropriate translation contexts:

text
var t1 = qsTranslate("symUserNames", "Sharp"); // gets a translation for "Sharp" symbol name
console.log(t1);
var t2 = qsTranslate("action", "Export parts"); // gets a translation for "Export parts" action
console.log(t2);

Translation contexts for existing strings can be searched for on Transifex or directly in MuseScore source code.

This method allows to quickly make a plugin translatable. Still, it may not fit a particular plugin's needs. \n
Translation contexts are not guaranteed to remain unchanged between MuseScore releases. Also, this method won't work if a plugin needs strings that are not used anywhere else in MuseScore.

Add translation files to the plugin

To make the plugin's strings translatable you need to use qsTr() for all your "quoted strings" in the .qml files. qsTr() has 3 arguments, the 1st is the string to be translated, the 2nd (optional) argument is a comment to the translator (which is later visible in Qt Linguist), the 3rd (also optional) is intended to be used for handling plurals in translations. \n
It can work with placeholders, e.g. qsTr("Pages: %1").arg(numberOfPages)

For translating \ref Ms::PluginAPI::PluginAPI::menuPath "menu item" of the plugin it is better not to translate the top-level item of menu path (usually "Plugins"):

text
menuPath: "Plugins." + qsTr("Note Names")

In order to avoid conflicts with other plugins' translations it is recommended to have a separate directory for your plugin (that is, plugin's .qml files should not be put directly to the Plugins directory but to a subdirectory created specifically for that plugin).

Then create a directory named translations in the plugin's directory. You need to put locale_XX.qm files in it. \n
To obtain a .qm file for your plugin run the following command: \n
(replace XX with the targetted language (eg.: "de" for German) and include .qml and .js files)

text
lupdate <your plugin files> translations/locale_XX.ts

This extracts all translatable strings from the .qml and .js files into that .ts file. \n
Repeat for other languages if needed.

Use Qt Linguist to put the translation into locale_XX.ts. Once done use File โ†’ Release in Qt Linguist or run the following:

text
lrelease translations/locale_XX.ts

That will create/update a locale_XX.qm file. \n
Now, run MuseScore in your language and your plugin should be translated!

More detailed information can be found in Qt documentation.

A working example of translation files usage can be found in Batch Export plugin.


Old Docs Pitch (`docs/old_docs/pitch.md`)

\page pitch Note Pitch values

Note pitches are internally expressed with their respective MIDI pitch values. This corresponds to the absolute height of the note, regardless of the way it is actually written (enharmony; to retrieve the actual enharmony employed for a note, use its \ref tpc "Tonal Pitch Class" instead).
The pitch is used by the \ref Ms::PluginAPI::Note::pitch "Note.pitch" property.

Note Pitch Values

Note \ Octave -1 0 1 2 3 4 5 6 7 8 9
C 0 12 24 36 48 60 (middle C) 72 84 96 108 120
Cโ™ฏ 1 13 25 37 49 61 73 85 97 109 121
D 2 14 26 38 50 62 74 86 98 110 122
Dโ™ฏ 3 15 27 39 51 63 75 87 99 111 123
E 4 16 28 40 52 64 76 88 100 112 124
F 5 17 29 41 53 65 77 89 101 113 125
Fโ™ฏ 6 18 30 42 54 66 78 90 102 114 126
G 7 19 31 43 55 67 79 91 103 115 127
Gโ™ฏ 8 20 32 44 56 68 80 92 104 116 --
A 9 21 33 45 57 69 81 93 105 117 --
Aโ™ฏ 10 22 34 46 58 70 82 94 106 118 --
B 11 23 35 47 59 71 83 95 107 119 --

Old Docs Plugins (`docs/old_docs/plugins.md`)

Welcome to the MuseScore plugins documentation!

This page gives a brief overview of the topics related to plugins development.

Plugin development overview

Here are some points concerning MuseScore plugin development:

Plugins are QML components.

MuseScore plugins are coded in
QML.
Each plugin is a QML component using which implements some logic inside its
instance of \ref Ms::PluginAPI::PluginAPI "MuseScore" class and are capable to
interact both with MuseScore API and with Qt itself (so MuseScore plugins can
create their own windows, dialogs). Most of the plugins are contained within a
single .qml file though they may contain more items like resources and
translation files.

Debugging plugins

MuseScore provides a simple plugin code editor which allows developing and
instantly testing the developed plugin. This editor can be launched with Plugins โ†’
Plugin Creator menu item or by pressing
Ctrl+Shift+P.

Clicking on a New button will create a sample plugin, you can also run your
plugin with the Run button and see some debugging output in the console window below
the editing area. In order to print some debugging messages to that console use
console.log():

text
var e = newElement(Element.STAFF_TEXT);
console.log("the created element:", e, e.name);

Alternatively, you can edit your plugin's code with your favourite text editor
and test it by launching it from MuseScore as long as the plugin is properly
installed. See this Handbook
page

for the reference on plugins installation.

Hello World plugin

Here is an example of a simple plugin which prints "Hello World" to the
debugging console:

text
import MuseScore 3.0

MuseScore {
    menuPath: "Plugins.pluginName"
    description: "Description goes here"
    version: "1.0"
    onRun: {
        console.log("Hello World!");
        Qt.quit();
    }
}

Here is what happens here.

  • import MuseScore 3.0 is necessary to use MuseScore API in QML code.
  • The MuseScore { ... } statement declares an object of MuseScore type (\ref
    Ms::PluginAPI::PluginAPI is exposed to QML as MuseScore). This should be
    the root object of any QML plugin for MuseScore.
  • Statements like menuPath: "Plugins.pluginName" assign properties to that
    object, see \ref
    Ms::PluginAPI::PluginAPI "the class reference" for the meaning of those
    properties. Apart from the properties listed in that page, you can assign any
    other properties and/or declare other QML objects too.
  • onRun() is the function that is invoked when the plugin is executed (via a
    menu entry or via a shortcut). This is the entry point of your plugin.
  • Qt.quit() statement
    requests termination of the plugin's execution.

Documentation from Earlier Versions

Although it is not up to date, documentation for creating plugins for earlier versions is available and may be useful.
https://musescore.org/en/handbook/developers-handbook/plugin-development

Plugins Installed By Default

MuseScore is shipped with a set of simple plugins which can also be used as
a reference while developing your own plugins.

ABC Import

This plugin imports ABC text from a file or the clipboard. Internet connection is required, because it uses an external web-service for the conversion, which uses abc2xml and gets send the ABC data, returns MusicXML and imports that into MuseScore.

Color Notes

This demo plugin colors notes in the selected range (or the entire score), depending on their pitch. It colors the note head of all notes in all staves and voices according to the Boomwhackers convention. Each pitch has a different color. C and Cโ™ฏ have different color. Cโ™ฏ and Dโ™ญ have the same color.
To color all the notes in black, just run that plugin again (on the same selection). You could also use the 'Remove Notes Color' plugin for this.

Create Score

This demo plugin creates a new score. It creates a new piano score with 4 quarters C D E F. It's a good start to learn how to make a new score and add notes from a plugin.

helloQml

This demo plugin shows some basic tasks.

Note Names

This plugin names notes in the selected range or the entire score. It displays the names of the notes (as a staff text) as per MuseScore's language settings, for voices 1 and 3 above the staff, for voices 2 and 4 below the staff, and for chords in a comma-separated list, starting with the top note.

Note Names -Interactive

This plugin names notes as per your language setting.

Panel

This demo plugin creates a GUI panel.

random

Creates a random score.

random2

Creates a random score too.

run

This demo plugin runs an external command. Probably this will only work on Linux.

scorelist

This test plugin iterates through the score list.

View

Demo plugin to demonstrate the use of a ScoreView

Walk

This test plugin walks through all elements in a score

Porting MuseScore 2 plugins

This documentation corresponds to the plugins API for MuseScore 3.X version.
To see the information on its difference from MuseScore 2 plugins API as well
as some instructions on adapting MuseScore 2 plugins code to work with
MuseScore 3, please refer to the \ref plugin2to3 page.

Internationalization

For the questions related to making a plugin translatable to different languages
please refer to https://github.com/musescore/MuseScore/blob/master/docs/i18n.md.


Old Docs Plugins2to3 (`docs/old_docs/plugins2to3.md`)

\page plugin2to3 Porting MuseScore 2 plugins

This page describes changes between MuseScore 2.X and MuseScore 3 plugins API.

Import statement

Replace import MuseScore 1.0 with import MuseScore 3.0 to start porting a 2.X plugin.
This is needed to distinguish between plugins for different MuseScore versions.

If your plugin uses \ref Ms::PluginAPI::FileIO "FileIO" API, replace also
import FileIO 1.0 with import FileIO 3.0.

Properties assignments

Most of the properties should remain the same as in MuseScore 2.X. Most notable differences:

  • TimeSig doesn't have setSig() function anymore. \par
    Replace
    \code ts.setSig(numerator, denominator) \endcode
    with
    \code ts.timesig = fraction(numerator, denominator) \endcode

  • No pos property available. \par
    The Autoplacement engine makes it not necessary to adjust elements' position in most cases.
    If this is still needed, use offset or offsetX and offsetY properties to adjust position offset:
    \code element.offset = Qt.point(x, y); \endcode
    or
    \code
    element.offsetX = x;
    element.offsetY = y;
    \endcode
    where x, y are arbitrary numbers (in spatium units).

.

Enumerations

Most of the enumerations exposed to QML plugins remain the same but some were renamed compared to MuseScore 2.X API. The renamed enumerations include:

  • \ref Ms::PluginAPI::PluginAPI::Placement "Placement" โ€” element placement above or below staff \par
    Element.ABOVE, Element.BELOW โ†’ Placement.ABOVE, Placement.BELOW

  • \ref Ms::PluginAPI::PluginAPI::Direction "Direction" โ€” vertical direction \par
    MScore.UP, MScore.DOWN, MScore.AUTO โ†’ Direction.UP, Direction.DOWN, Direction.AUTO

  • \ref Ms::PluginAPI::PluginAPI::DirectionH "DirectionH" โ€” horizontal direction \par
    MScore.LEFT, MScore.RIGHT, MScore.AUTO โ†’ DirectionH.LEFT, DirectionH.RIGHT, DirectionH.AUTO

  • \ref Ms::PluginAPI::PluginAPI::OrnamentStyle "OrnamentStyle" \par
    MScore.DEFAULT, MScore.BAROQUE โ†’ OrnamentStyle.DEFAULT, OrnamentStyle.BAROQUE

  • \ref Ms::PluginAPI::PluginAPI::GlissandoStyle "GlissandoStyle" \par
    MScore.CHROMATIC, MScore.WHITE_KEYS, MScore.BLACK_KEYS, MScore.DIATONIC
    โ†’
    GlissandoStyle.CHROMATIC etc.

  • TextStyleType โ†’ \ref Ms::PluginAPI::PluginAPI::Tid "Tid"

  • \ref Ms::PluginAPI::PluginAPI::NoteHeadType "NoteHeadType" \par
    HEAD_AUTO, HEAD_WHOLE, HEAD_HALF, HEAD_QUARTER, HEAD_BREVIS, HEAD_TYPES are now in NoteHeadType enumeration.

  • \ref Ms::PluginAPI::PluginAPI::NoteHeadGroup "NoteHeadGroup" \par
    Other HEAD_* values are in NoteHeadGroup enumeration.

  • \ref Ms::PluginAPI::PluginAPI::NoteValueType "NoteValueType" \par
    Note.OFFSET_VAL, Note.USER_VAL โ†’ NoteValueType.OFFSET_VAL, NoteValueType.USER_VAL


Old Docs Ticklength (`docs/old_docs/ticklength.md`)

\page ticklength Tick Length values

Note and rest values are expressed in an internal unit, to express their mutual relationships and to make them independent from actual tempo. This unit is used by the following object properties:

  • \ref Ms::PluginAPI::PluginAPI::division (defines a number of ticks per quarter note)
  • \ref Ms::PluginAPI::Segment::tick
  • Other properties (to be added to this list)

Tick Lengths

All tick lengths in this table are defined through the \ref Ms::PluginAPI::PluginAPI::division "division" property. Raw numeric values are better to be avoided.

Duration Ticks value
whole note (semibreve) 4 * division
double-dotted half note 3.5 * division
dotted half note 3 * division
triplet whole note (1/3 of breve) 8 * division / 3
half note (minim) 2 * division
double-dotted crochet 1.75 * division
dotted crochet 1.5 * division
triplet half note (1/3 of semibreve) 4 * division / 3
1/4 note (crochet) division
double-dotted quaver 0.875 * division
dotted quaver 0.75 * division
triplet crochet (1/3 of minim) 2 * division / 3
1/8 note (quaver) division / 2
double-dotted semiquaver 0.4375 * division
dotted semiquaver 0.375 * division
triplet quaver (1/3 of crochet) division / 3
1/16 note (semiquaver) division / 4
double-dotted demi-semiquaver 0.21875 * division
dotted demi-semiquaver 0.1875 * division
triplet semiquaver (1/3 of quaver) division / 6
1/32 note (demi-semiquaver) division / 8
dotted hemi-demi-semiquaver 0.09375 * division
triplet demi-semiquaver (1/3 of semiquaver) division / 12
1/64 note (hemi-demi-semiquaver) division / 16

Old Docs Tpc (`docs/old_docs/tpc.md`)

\page tpc Tonal Pitch Class

The Tonal Pitch Class (tpc) is used to differentiate among notes with the same MIDI pitch but with different representation (also covering enharmony). The tpc is used by the following properties:

  • \ref Ms::PluginAPI::Note::tpc1
  • \ref Ms::PluginAPI::Note::tpc2
  • \ref Ms::PluginAPI::Note::tpc

Tonal Pitch Classes in numeric order

tpc name tpc name tpc name tpc name tpc name
-1 Fโ™ญโ™ญ 6 Fโ™ญ 13 F 20 Fโ™ฏ 27 Fโ™ฏโ™ฏ
0 Cโ™ญโ™ญ 7 Cโ™ญ 14 C 21 Cโ™ฏ 28 Cโ™ฏโ™ฏ
1 Gโ™ญโ™ญ 8 Gโ™ญ 15 G 22 Gโ™ฏ 29 Gโ™ฏโ™ฏ
2 Dโ™ญโ™ญ 9 Dโ™ญ 16 D 23 Dโ™ฏ 30 Dโ™ฏโ™ฏ
3 Aโ™ญโ™ญ 10 Aโ™ญ 17 A 24 Aโ™ฏ 31 Aโ™ฏโ™ฏ
4 Eโ™ญโ™ญ 11 Eโ™ญ 18 E 25 Eโ™ฏ 32 Eโ™ฏโ™ฏ
5 Bโ™ญโ™ญ 12 Bโ™ญ 19 B 26 Bโ™ฏ 33 Bโ™ฏโ™ฏ

Tonal Pitch Classes in pitch order

pitch tpc name tpc name tpc name
11 31 Aโ™ฏโ™ฏ 19 B 7 Cโ™ญ
10 24 Aโ™ฏ 12 Bโ™ญ 0 Cโ™ญโ™ญ
9 29 Gโ™ฏโ™ฏ 17 A 5 Bโ™ญโ™ญ
8 22 Gโ™ฏ 10 Aโ™ญ
7 27 Fโ™ฏโ™ฏ 15 G 3 Aโ™ญโ™ญ
6 32 Eโ™ฏโ™ฏ 20 Fโ™ฏ 8 Gโ™ญ
5 25 Eโ™ฏ 13 F 1 Gโ™ญโ™ญ
4 30 Dโ™ฏโ™ฏ 18 E 6 Fโ™ญ
3 23 Dโ™ฏ 11 Eโ™ญ -1 Fโ™ญโ™ญ
2 28 Cโ™ฏโ™ฏ 16 D 4 Eโ™ญโ™ญ
1 33 Bโ™ฏโ™ฏ 21 Cโ™ฏ 9 Dโ™ญ
0 26 Bโ™ฏ 14 C 2 Dโ™ญโ™ญ

Apidocs Static Tutorials 1 Getting Started (`docs/apidocs_static/tutorials/1_getting_started.md`)

Adding a new non-visual extension

Create a new folder in the user extensions folder:

  • Windows - C:\Users\username\AppData\Local\MuseScore\MuseScore5\extensions
  • MacOS -
  • Linux - $HOME/.local/share/MuseScore/MuseScore5/extensions

for example myquickstart.

In this folder, create a new file manifest.json
Fill out the manifest as follows:

text
{
    "uri": "musescore://extensions/myquickstart",
    "type": "macros",
    "title": "My quick start",
    "description": "This is a development extension for API research.",

    "actions": [
        {
            "path": "main.js"
        }
    ]
}

Create a new file main.js
Fill out as follows:

text
const Log = require("MuseApi.Log");
const Interactive = require("MuseApi.Interactive");

function main() {
    Log.info("called main from quickstart")
    Interactive.info("Quick start", "called MAIN from quickstart")
}

Launch MuseScore and enable your extension on the plugins page.
Open a project (some a score or create new) and call your extension from the plugins menu.
A dialog should be displayed with information from your extension.

Congratulations! You've created and added a new extension!

Adding a new visual extension

Create a new folder in the custom extensions folder:

  • Windows - C:\Users\username\AppData\Local\MuseScore\MuseScore5\extensions
  • MacOS -
  • Linux - $HOME/.local/share/MuseScore/MuseScore5/extensions

for example myquickstart_v.

In this folder, create a new file manifest.json
Fill out the manifest as follows:

text
{
    "uri": "musescore://extensions/myquickstart_v",
    "type": "form",
    "title": "My quick start visual",
    "description": "This is a development extension for API research.",

    "actions": [
        {
            "path": "Main.qml"
        }
    ]
}

Create a new file Main.qml
Fill out as follows:

text
import QtQuick

import MuseApi.Controls
import MuseApi.Interactive

ExtensionBlank {

    id: root

    implicitHeight: 400
    implicitWidth: 400

    StyledTextLabel {
        id: label1
        anchors.centerIn: parent
        text: "Quick start"
    }

    FlatButton {
        id: btn1
        anchors.top: label1.bottom
        anchors.topMargin: 8
        anchors.horizontalCenter: parent.horizontalCenter

        text: "Click me"

        onClicked: {
            Interactive.info("Quick start", "Clicked on button")
        }
    }
}

Launch MuseScore and enable your extension on the plugins page.
Open a project (some a score or create new) and call your extension from the plugins menu.
A dialog with you form.

Congratulations! You've created and added a new visual extension!


Apidocs Static Tutorials 2 Manifest (`docs/apidocs_static/tutorials/2_manifest.md`)

Each extension must contain a manifest.json file. This is what is searched for to detect the extension and obtain information about it.

manifest.json

text
{
    "uri": "musescore://extensions/myquickstart",
    "type": "macros",
    "title": "My quick start",
    "description": "This is a development extension for API research.",
    "thumbnail": "my_icon.png",
    "version":  "0.1",
    "vendor": "Me"
    "ui_context": "Any",
    "apiversion": 2,

    "actions": [
        {
            "path": "main.js"
        }
    ]
}

uri (required)

This is the extension identifier, used to call it.
It must be unique and follow the pattern: musescore://extensions/extensions_name

type (required)

Type of extension

  • macros - extension without user interface
  • form - extension with user interface
  • composite - extension consisting of several forms or forms and macros

title (required)

Title of extension. Please write a concise and clear title.

description (required)

Description of extension. Please write a one-sentence description to make it clear what this extension does.

thumbnail (optional)

Thumbnail of extension. PNG format is supported.

category (optional)

Category of extension.

version (optional)

Version of extension.

vendor (optional)

About the author

apiversion (optional)

The API version used:

  • 1 - api of old plugins, deprecated, don't use this for new extensions
  • 2 (default) - actual api

ui_context (optional)

The context in which the extension is available:

  • ProjectOpened (default) - Project (score) open
  • Any - always available

actions (required)

List of extension actions.
An extension typically has one action, but can have multiple.
Actions are displayed as menu items in Menu->Plugins by default.
However, they can also be displayed as buttons on the toolbar.

example

text
...
    "actions": [
        {"code": "configure", "type": "form", "title": "Configure", "path": "configure.qml"},
        {"code": "add", "type": "macros", "title": "Add", "path": "add.js"},
        {"code": "remove", "type": "macros", "title": "Remove", "path": "remove.js"}
    ]

action: code (optional)

Action code

action: type (required for type `composite`/optional for `form`/`macros`)

If an extension consists of forms and macros (type composite), then you must specify the type of each action. If the extension has a single action, or all actions are of the same type, then you don't need to specify it; the action type will be equivalent to the extension type.

action: title (optional)

The action title, if not specified, will be equivalent to the extension title.

action: icon (optional)

Action icon, displayed in the menu or on the toolbar.
see {@link Qml.IconCode|IconCode}

action: ui_context (optional)

The context in which the action is available.
If not specified, then equivalent to the extension ui_context.

action: show_on_appmenu (optional)

Whether to show the action in the menu. Default is true.

action: show_on_toolbar (optional)

Whether to show the action on the toolbar. Default is false.

action: path (required)

Path to the js script of macros or Qml form

action: func (optional)

For macros only. The name of the function to call.
This means you can specify the same script file but different functions for different actions.
If not specified, the default function name is main.


Apidocs Static Tutorials 3 Form (`docs/apidocs_static/tutorials/3_form.md`)

Extension Forms

Forms are extensions that have a user interface. To create UI, Qml is used. For form extensions, we need to specify the appropriate type and file name using .qml in the extension manifest.
Like this:
manifest.json

text
{
    "uri": "musescore://extensions/example1",
    "type": "form",
    ...

    "actions": [
        {
            "path": "Main.qml"
        }
    ]
}

To create a UI, use ExtensionBlank as the root element and the provided UI component library. For this we need to do import MuseApi.Controls. You can also use the various services provided, which are described in the documentation.

Example of a simple interface:

text
import QtQuick

import MuseApi.Controls
import MuseApi.Log
import MuseApi.Interactive

ExtensionBlank {

    id: root

    implicitHeight: 400
    implicitWidth: 400

    Component.onCompleted: {
        Log.info("Component.onCompleted from example1")
    }

    StyledTextLabel {
        id: label1
        text: "This is example1"
    }

    FlatButton {
        id: btn1
        anchors.top: label1.bottom

        text: "Click me"

        onClicked: {
            Interactive.info("Example1", "Clicked on Btn1")
        }
    }
}

Apidocs Static Tutorials 4 Macros (`docs/apidocs_static/tutorials/4_macros.md`)

Extension Macros

Macros are extensions that do not have a user interface, there is only a script that does something. Usually this is a way to automate some actions.
For macros extensions, we need to specify the appropriate type and file name using .js in the extension manifest.
Like this:
manifest.json

text
{
    "uri": "musescore://extensions/example1",
    "type": "macros",
    ...

    "actions": [
        {
            "path": "main.js"
        }
    ]
}

In the manifest you can specify the name of the function that will be called; if not specified, then the main function will be called by default. You can also use the various services provided, which are described in the documentation.

main.js

text
const Log = require("MuseApi.Log");
const Interactive = require("MuseApi.Interactive");

function main() {
    Log.info("called main from example 2")
    Interactive.info("Quick start", "called main from example 2")
}

--- METRICS ---