QML boilerplates
If you are editing qmllearning, please upload a file too so that if the page is overwritten accidentally your code can still be retrieved. Discuss this page at https://musescore.org/en/node/345584
parkingb
- automatic window dimension based on UI content
- use of the SystemPalette.Active and SystemPalette.Disabled for proper color management
- Rely on DialogButtonBox for correct button placement
- use as much as possible native MuseScore translations.
The latter can be tricky because translations structure differs from MS3 and MS4.
E.g. for a "title" label:
text: mscoreMajorVersion > 3 ? qsTranslate("project", "Title") + ":" : qsTranslate("NewWizard", "Title") + ":"
-
automatic execution of code (such as settings management) when the window is closed.
qmllearning Dialog
Demo version 20230227A
- automatic window dimension show all content
- option to set fixed size instead
- scrollable contentarea
- does not require UI building pixel by pixel
- does not use pluginType:Dialog
- does not use quit or Qt.quit()
- wrap and reflow
Column{ Flow{ Item{} Item{}...}}
(need to set a wrap width)
TODO
- study parkingb's
mainWindow.parent.Window.window.close();
- Settings{}
Download: musescore_qmllearning_20230301A.zip
Overview version 20230227A:
View Raw:
import MuseScore 3.0 import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.2 import QtQuick.Dialogs 1.2 import QtQuick.Window 2.2 MuseScore { menuPath: "Plugins.QMLlearning_Dialog" version: "20230301A" id: pluginscope property real wrapperwidth: 600 // use Screen if you need ratio based ui property bool fixsize:false property int pagemargintb:10; property int pagemarginlr:20 // use Screen if you need ratio based ui property real customwidth: Screen.desktopAvailableWidth*.2 property real customheight: Screen.desktopAvailableHeight*.2 onRun:{ if(fixsize){ plugindialog.width =Math.min(customwidth ,Screen.desktopAvailableWidth) plugindialog.height=Math.min(customheight ,Screen.desktopAvailableWidth) }else{ // plugindialog doesn't auto expand by contentItem : qml bug ? plugindialog.width =Math.min( Math.max(wrapperwidth, plugincontent.width) ,Screen.desktopAvailableWidth) // height is tricky setTimeout.createObject(pluginscope,{ interval:1 ,running:true }).triggered.connect(function(){ plugindialog.height=Math.min( grid.height+plugincontent.header.height+plugincontent.footer.height ,Screen.desktopAvailableHeight) }) } } Component { id: setTimeout ; Timer { } } Dialog { id:plugindialog title: "PluginDialog" visible:true contentItem:Page{ id:plugincontent header: ToolBar { // ToolBar, TabBar, or DialogButtonBox background: Rectangle { color: "skyblue"} RowLayout{ anchors.fill: parent Label{ horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter Layout.fillWidth: true text: "header" color: "navy" } ToolButton { text: 'btn1' onClicked: console.log('btn1') } ToolButton { text: 'btn2' onClicked: { console.log('btn2') } } ToolButton { text: 'btn3' onClicked: function(){ console.log('btn3') } } } } contentItem:Rectangle{ id:pagecontent color: "beige" Flickable{ anchors.fill:parent; contentWidth: grid.width; contentHeight: grid.height GridLayout{ id:grid columns: 1 Column{ id:allcontent Layout.preferredWidth: pagecontent.width-Layout.leftMargin-Layout.rightMargin Layout.leftMargin : pagemarginlr; Layout.rightMargin :pagemarginlr Layout.topMargin : pagemargintb; Layout.bottomMargin :pagemargintb Column{ id:innercontent width: parent.width // // Contents here Rectangle{ color: "red" ;height: 20 ;width:parent.width } Rectangle{ color: "green" ;height: 20 ;width:parent.width /2 } Rectangle{ color: "blue" ;height: 20 ;width:parent.width /2 } Flow{ width: parent.width Rectangle{ color: "cyan" ;height:50 ;width:50 } //dont' assign width with Flow's width, it will cause infinite loop Rectangle{ color: "yellow" ;height:50 ;width:50 } Rectangle{ color: "magenta" ;height:50 ;width:50 } Rectangle{ color: "black" ;height:50 ;width:50 } Rectangle{ color: "cyan" ;height:50 ;width:50 } Rectangle{ color: "yellow" ;height:50 ;width:50 } Rectangle{ color: "magenta" ;height:50 ;width:50 } Rectangle{ color: "black" ;height:50 ;width:50 } Rectangle{ color: "cyan" ;height:20 ;width:20 } Rectangle{ color: "yellow" ;height:20 ;width:20 } Rectangle{ color: "magenta" ;height:20 ;width:20 } Rectangle{ color: "black" ;height:20 ;width:20 } Rectangle{ color: "cyan" ;height:20 ;width:20 } Rectangle{ color: "yellow" ;height:20 ;width:20 } Rectangle{ color: "magenta" ;height:20 ;width:20 } Rectangle{ color: "black" ;height:20 ;width:20 } Rectangle{ color: "purple" height:50; width:parent.parent.width/2 //safe to assign width with id=allcontent's width Text { anchors.fill:parent verticalAlignment: Qt.AlignVCenter text: 'VCenter' } } Rectangle{ color: "pink" height:50; width:parent.parent.width/4 Text { anchors.centerIn:parent text: 'Centered' } } Button { text: 'btnC' onClicked: function(){ console.log('btnC') } } Text { width:parent.parent.width wrapMode: Text.WordWrap text: " Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Arcu cursus euismod quis viverra nibh cras. Vulputate enim nulla aliquet porttitor lacus. Sed cras ornare arcu dui. Dui vivamus arcu felis bibendum. Porttitor massa id neque aliquam vestibulum morbi blandit cursus risus. Nullam ac tortor vitae purus faucibus ornare suspendisse sed. Amet porttitor eget dolor morbi. Leo a diam sollicitudin tempor id eu. Vitae semper quis lectus nulla at. Quam adipiscing vitae proin sagittis nisl rhoncus. A erat nam at lectus. Pretium vulputate sapien nec sagittis aliquam malesuada. Rhoncus dolor purus non enim praesent elementum facilisis leo vel. Vestibulum sed arcu non odio euismod lacinia at quis risus. Turpis cursus in hac habitasse platea. Ut consequat semper viverra nam libero justo laoreet sit amet.\n Hendrerit gravida rutrum quisque non tellus orci ac auctor. Scelerisque purus semper eget duis at tellus at. Suspendisse potenti nullam ac tortor. Adipiscing elit ut aliquam purus sit amet luctus. Massa sed elementum tempus egestas sed sed risus pretium. Risus quis varius quam quisque id. Ut sem nulla pharetra diam sit amet. Fames ac turpis egestas sed tempus. Elit eget gravida cum sociis. Adipiscing at in tellus integer feugiat. Lectus mauris ultrices eros in cursus turpis. Vel fringilla est ullamcorper eget nulla facilisi. At varius vel pharetra vel. Erat velit scelerisque in dictum non consectetur a. Lorem sed risus ultricies tristique nulla aliquet enim tortor at." } } Rectangle{ color: "red" ;height: 20 ;width:parent.width } Rectangle{ color: "green" ;height: 20 ;width:parent.width /2 } Rectangle{ color: "blue" ;height: 20 ;width:parent.width /2 } } } } } } footer: DialogButtonBox { // ToolBar, TabBar, or DialogButtonBox // ms3 Page footer is not bugged background: Rectangle { color: "darkgrey"} Button { text: 'OK' DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole } Button { text: 'Cancel' DialogButtonBox.buttonRole: DialogButtonBox.RejectRole } onAccepted: { console.log("ok") } onRejected: { console.log("cancel"); plugindialog.visible=false } } } // footer: Item{} // ms3 Dialog bug : Cannot assign to non-existent property "footer" } }
Old versions:
qmllearning_20230227A.qml Add show all content, set fix size, scrollable contentarea
qmllearning_20230226A.qml
qmllearning_20230226B.qml : Add show all content (edit: revert back to A, B does not work in ms4)
qmllearning_20230226C.qml : Add optional set init size (edit: revert back to A, C does not work in ms4)
qmllearning Dockable
Same as the above dialog variant but use pluginType: "dock"
pluginscope.height not working
Download: musescore_qmllearning_20230301A.zip
View Raw:
import MuseScore 3.0 import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.2 import QtQuick.Dialogs 1.2 import QtQuick.Window 2.2 MuseScore { menuPath: "Plugins.QMLlearning_Dockable" version: "20230301A" id: pluginscope pluginType: "dock" property real wrapperwidth: 600 // use Screen if you need ratio based ui property int pagemargintb:10; property int pagemarginlr:20 // use Screen if you need ratio based ui property real customwidth: Screen.desktopAvailableWidth*.2 property real customheight: Screen.desktopAvailableHeight*.2 onRun:{ pluginscope.height=Math.min(customheight ,Screen.desktopAvailableWidth) } Page{ id:plugincontent anchors.fill: parent header: ToolBar { // ToolBar, TabBar, or DialogButtonBox background: Rectangle { color: "skyblue"} RowLayout{ anchors.fill: parent Label{ horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter Layout.fillWidth: true text: "header" color: "navy" } ToolButton { text: 'btn1' onClicked: console.log('btn1') } ToolButton { text: 'btn2' onClicked: { console.log('btn2') } } ToolButton { text: 'btn3' onClicked: function(){ console.log('btn3') } } } } contentItem:Rectangle{ id:pagecontent color: "beige" Flickable{ anchors.fill:parent; contentWidth: grid.width; contentHeight: grid.height GridLayout{ id:grid columns: 1 Column{ id:allcontent Layout.preferredWidth: pagecontent.width-Layout.leftMargin-Layout.rightMargin Layout.leftMargin : pagemarginlr; Layout.rightMargin :pagemarginlr Layout.topMargin : pagemargintb; Layout.bottomMargin :pagemargintb Column{ id:innercontent width: parent.width // // Contents here Rectangle{ color: "red" ;height: 20 ;width:parent.width } Rectangle{ color: "green" ;height: 20 ;width:parent.width /2 } Rectangle{ color: "blue" ;height: 20 ;width:parent.width /2 } Flow{ width: parent.width Rectangle{ color: "cyan" ;height:50 ;width:50 } //dont' assign width with Flow's width, it will cause infinite loop Rectangle{ color: "yellow" ;height:50 ;width:50 } Rectangle{ color: "magenta" ;height:50 ;width:50 } Rectangle{ color: "black" ;height:50 ;width:50 } Rectangle{ color: "cyan" ;height:50 ;width:50 } Rectangle{ color: "yellow" ;height:50 ;width:50 } Rectangle{ color: "magenta" ;height:50 ;width:50 } Rectangle{ color: "black" ;height:50 ;width:50 } Rectangle{ color: "cyan" ;height:20 ;width:20 } Rectangle{ color: "yellow" ;height:20 ;width:20 } Rectangle{ color: "magenta" ;height:20 ;width:20 } Rectangle{ color: "black" ;height:20 ;width:20 } Rectangle{ color: "cyan" ;height:20 ;width:20 } Rectangle{ color: "yellow" ;height:20 ;width:20 } Rectangle{ color: "magenta" ;height:20 ;width:20 } Rectangle{ color: "black" ;height:20 ;width:20 } Rectangle{ color: "purple" height:50; width:parent.parent.width/2 //safe to assign width with id=allcontent's width Text { anchors.fill:parent verticalAlignment: Qt.AlignVCenter text: 'VCenter' } } Rectangle{ color: "pink" height:50; width:parent.parent.width/4 Text { anchors.centerIn:parent text: 'Centered' } } Button { text: 'btnC' onClicked: function(){ console.log('btnC') } } Text { width:parent.parent.width wrapMode: Text.WordWrap text: " Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Arcu cursus euismod quis viverra nibh cras. Vulputate enim nulla aliquet porttitor lacus. Sed cras ornare arcu dui. Dui vivamus arcu felis bibendum. Porttitor massa id neque aliquam vestibulum morbi blandit cursus risus. Nullam ac tortor vitae purus faucibus ornare suspendisse sed. Amet porttitor eget dolor morbi. Leo a diam sollicitudin tempor id eu. Vitae semper quis lectus nulla at. Quam adipiscing vitae proin sagittis nisl rhoncus. A erat nam at lectus. Pretium vulputate sapien nec sagittis aliquam malesuada. Rhoncus dolor purus non enim praesent elementum facilisis leo vel. Vestibulum sed arcu non odio euismod lacinia at quis risus. Turpis cursus in hac habitasse platea. Ut consequat semper viverra nam libero justo laoreet sit amet.\n Hendrerit gravida rutrum quisque non tellus orci ac auctor. Scelerisque purus semper eget duis at tellus at. Suspendisse potenti nullam ac tortor. Adipiscing elit ut aliquam purus sit amet luctus. Massa sed elementum tempus egestas sed sed risus pretium. Risus quis varius quam quisque id. Ut sem nulla pharetra diam sit amet. Fames ac turpis egestas sed tempus. Elit eget gravida cum sociis. Adipiscing at in tellus integer feugiat. Lectus mauris ultrices eros in cursus turpis. Vel fringilla est ullamcorper eget nulla facilisi. At varius vel pharetra vel. Erat velit scelerisque in dictum non consectetur a. Lorem sed risus ultricies tristique nulla aliquet enim tortor at." } } Rectangle{ color: "red" ;height: 20 ;width:parent.width } Rectangle{ color: "green" ;height: 20 ;width:parent.width /2 } Rectangle{ color: "blue" ;height: 20 ;width:parent.width /2 } } } } } } footer: DialogButtonBox { // ToolBar, TabBar, or DialogButtonBox // ms3 Page footer is not bugged background: Rectangle { color: "darkgrey"} Button { text: 'OK' DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole } Button { text: 'Cancel' DialogButtonBox.buttonRole: DialogButtonBox.RejectRole } onAccepted: { console.log("ok") } onRejected: { console.log("cancel") } } } }