QML (Qt Modeling Language) is a user interface markup language that JASP uses to show the analysis input panel. In this panel the user can specify what options should be set to what values and thereby change the tables and plots that the analysis computes. QML is a very flexible language that allows us to easily generate checkboxes, dropdowns and other common interface components. It also gives the possiblility to insert JavaScript expressions to dynamically alter the interface based on actions a user makes. To create a more uniform layout and make it easier to add new analyses we have provided a number of standardized components. These components should satify most analysis creators, although you can always add your own. To write a QML form you should follow the styleguide.
Table of Contents:
The components can roughly be divided in three classes. One that deals with general inputs (e.g., checkboxes), one that deals with assigning variables and one that groups components together. Each will be covered in the following section. Some remarks about these components:
- They are all QML items, so they automatically get generic QML properties like
enabled
orvisible
. - The properties of the components can be set directly with a value. You can use also a JavaScript expression so that the value will depend on other components (see the section on Connecting Multiple Components).
- In several examples you may encounter
qsTr()
, it is important that this function wraps all text that will be shown in the interface. It will provide the possibility to translate JASP in the future. - The components described below may generally be nested to an arbitrary level (e.g., a checkbox in a group in a checkbox).
All (well almost all) of these components have a property name
that is also used in JASP-files to store the value the user selected. That means that whenever you change name
for a component for a newer version of your analysis/module the stored value will be ignored. To make sure the user entered information isn't lost you can add an upgrade.json to your module.
These components are quite common in questionnaires and input forms on websites, they include the checkbox, radiobutton, dropdown, slider and textfields where text may be entered.
Check button that can be toggled on and off. If some components are nested inside a CheckBox, they are automatically enabled or disabled when the CheckBox is set or not. Properties
name
: string identifier (in your R code you will be able to retrieve the value of the checkbox through this identifier)label
: text that will be shown to the left of the checkboxchecked
: [optional, default:false
] boolean specifying if it should be set per default on or not.childrenOnSameRow
: [optional, default:false
] boolean specifying if components (e.g., other checkboxes, textfields) nested within the checkbox should be shown on the same row or, alternatively, below the checkboxcolumns
: [optional, default:1
] integer specifying how many columns the nested components should occupy (e.g., when set to 3, with three nested checkboxes, these three checkboxes will appear side by side on the same horizontal row)
Examples
CheckBox { name: "pearson"; label: qsTr("Pearson"); checked: true }
CheckBox
{
name: "homogeneityCorrections"
label: qsTr("Homogeneity corrections")
columns: 3
CheckBox { name: "homogeneityNone"; label: qsTr("None") ; checked: true }
CheckBox { name: "homogeneityBrown"; label: qsTr("Brown-Forsythe") ; checked: true }
CheckBox { name: "homogeneityWelch"; label: qsTr("Welch") ; checked: true }
}
A RadioButton is used with other RadioButton's inside a RadioButtonGroup
. Contrary to CheckBox, only 1 RadioButton can be checked at the same time.
RadioButtonGroup properties:
name
: string identifier (in your R code you will be able to retrieve the value of the checked radiobutton through this identifier)title
: text that is shown above the set of radiobuttonsradioButtonsOnSameRow
: [optional, default:false
] per default, the RadioButton's are placed vertically under the title. Set this property to true to place the buttons horizontally.columns
: [optional, default:1
] integer specifying how many columns should be used to display the RadioButton's
RadioButton properties:
value
: the value of theRadioButtonGroup
that is send to R when this radiobutton is checkedlabel
: the text that is shown to the right of the radiobuttonchecked
: [optional, default:false
] boolean specifying if it should contain a checkmark (and thus be the default); one radiobutton should have this property set totrue
childrenOnSameRow
: [optional, default:false
] boolean specifying if components (e.g., checkboxes, textfields) nested within the radiobutton should be shown on the same row or, alternatively, below the radiobuttoncolumns
: [optional, default:1
] integer specifying how many columns the nested components should occupy (e.g., when set to 3, with three nested checkboxes, these three checkboxes will appear side by side on the same horizontal row)
Examples
RadioButtonGroup
{
name: "countProp"
title: qsTr("Display")
RadioButton { value: "descCounts"; label: qsTr("Counts"); checked: true }
RadioButton { value: "descProps"; label: qsTr("Proportions") }
}
RadioButtonGroup
{
name: "steppingMethodCriteriaType"
title: qsTr("Stepping Method Criteria")
RadioButton
{
value: "usePValue"; label: qsTr("Use p value"); checked: true
columns: 2
DoubleField { name: "steppingMethodCriteriaPEntry"; label: qsTr("Entry"); fieldWidth: 60; defaultValue: 0.05; max: 1; decimals: 3 }
DoubleField { name: "steppingMethodCriteriaPRemoval"; label: qsTr("Removal"); fieldWidth: 60; defaultValue: 0.1; max: 1; decimals: 3 }
}
RadioButton
{
value: "useFValue"; label: qsTr("Use F value")
columns: 2
DoubleField { name: "steppingMethodCriteriaFEntry"; label: qsTr("Entry"); fieldWidth: 60; defaultValue: 3.84; decimals: 3 }
DoubleField { name: "steppingMethodCriteriaFRemoval"; label: qsTr("Removal"); fieldWidth: 60; defaultValue: 2.71; decimals: 3 }
}
}
Properties
name
: string identifier (in your R code you will be able to retrieve the value of the dropdown through this identifier)label
: [optional, default:""
] text that will be shown above the dropdownvalues
: [optional, default: empty] array of (named) values that is shown in the dropdown list, in the case of an unnamed array the value and the label are the same, but when a named array is provided the label shown to the user can be different from the value send to R (see example below)indexDefaultValue
: [optional, default:0
] integer specifying the index of the dropdown item that is selected by default, take note that the numbering starts at zerosource
: [optional, default: empty] ifvalues
is empty, you can use the name of a VariablesList (see Variable Specification) to set the source of the values of the DropDown. Is source is also empty, then all available columns of the dataset are used.addEmptyValue
: [optional, default:false
] iftrue
, add an empty value with a place holder (seeplaceHolderText
) as first element of the dropdown listplaceHolderText
: [optional, default:<no choice>
] name used if an ampty value is added in the dropdown list
Examples
DropDown
{
name: "orthogonalSelector"
values: ["none", "varimax", "quartimax", "bentlerT", "equamax", "varimin"]
}
DropDown
{
name: "sumOfSquares"
indexDefaultValue: 2
label: qsTr("Sum of squares")
values:
[
{ label: "Type \u2160", value: "type1"},
{ label: "Type \u2161", value: "type2"},
{ label: "Type \u2162", value: "type3"}
]
}
Slider is used to select a value by sliding a handle along a track. Properties
name
: string identifier (in your R code you will be able to retrieve the value of the slider through this identifier)label
: [optional, default:""
] text that will be shown above the slidervalue
: [optional, default:0.5
] default valuemin
: [optional, default:0
] minimum valuemax
: [optional, default:1
] maximum valuevertical
: [optional, default:true
] set whether the slider should be displayed vertically or horizontallydecimals
: [optional, default:2
] set the number of decimals the value gets
Properties
name
: string identifier (in your R code you will be able to retrieve the value of the field through this identifier)label
: [optional, default:""
] text that will be shown to the left of the fieldafterLabel
: [optional, default:""
] text that will be shown to the right of the fielddefaultValue
: [optional, default:0
] numeric specifying the default value shown; can be an integer or a decimal value, just be sure to use a dot and not a commanegativeValues
: [optional, default:false
] specifies if the user should be able to input negative values (works only when themin
argument is omitted)min
: [optional, default:0
if negativeValues isfalse
, otherwise-Infinity
] numeric specifying the minimum value a user can entermax
: [optional, default:Infinity
] numeric specifying the maximum value a user can enterinclusive
: [optional, default:JASP.MinMax
, possible values:JASP.MinMax
,JASP.MinOnly
,JASP.MaxOnly
,JASP.None
] specify whether themin
andmax
parameters are inclusive or not. For example ifmin
is1
andinclusive
isJASP.MinMax
orJASP.MinOnly
then value1
is allowed.decimals
: [optional, default:3
] integer specifying how many decimals the user can enterfieldWidth
: [optional, default:40
] in pixels how wide should the field be
Examples
DoubleField
{
name: "eigenValuesBox"
label: qsTr("Eigenvalues above")
defaultValue: 1
decimals: 1
}
DoubleField
{
name: "priorFixedEffects"
label: qsTr("r scale fixed effects")
defaultValue: 0.5
fieldWidth: 50
max: 2
decimals: 1
}
Properties
name
: string identifier (in your R code you will be able to retrieve the value of the field through this identifier)label
: [optional, default:""
] text that will be shown to the left of the fieldafterLabel
: [optional, default:""
] text that will be shown to the right of the fielddefaultValue
: [optional, default:0
] integer specifying the default value shownnegativeValues
: [optional, default:false
] specifies if the user should be able to input negative values (works only when themin
argument is omitted)min
: [optional, default:0
if negativeValues isfalse
, otherwise-Infinity
] integer specifying the minimum value a user can entermax
: [optional, default:Infinity
] integer specifying the maximum value a user can enterinclusive
: [optional, default:yes
, possible values:yes
,minOnly
,maxOnly
,no
] specify whether themin
andmax
parameters are inclusive or not. For example ifmin
is1
andinclusive
isyes
orminOnly
then value1
is allowed.fieldWidth
: [optional, default:40
] in pixels how wide should the field be
Examples
IntegerField
{
name: "fixedSamplesNumber"
label: qsTr("No. samples")
defaultValue: 10000
fieldWidth: 60
}
IntegerField
{
name: "percentileValuesEqualGroupsNo"
min: 1
max: 1000
defaultValue: 4
afterLabel: qsTr(" equal groups")
}
Properties
name
: string identifier (in your R code you will be able to retrieve the value of the field through this identifier)label
: text that will be shown to the left of the fieldafterLabel
: [optional, default%
] text that will be shown to the right of the fielddefaultValue
: [optional, default:50
] integer specifying the default percentage shownfieldWidth
: [optional, default:40
] in pixels how wide should the field bedecimals
: [optional, default:0
] integer specifying how many decimals the user can enter
Specialized control for Confident Interval Input field (with right default values)
Properties:
name
: string identifier (in your R code you will be able to retrieve the value of the field through this identifier)label
: [optional, default:""
] text that will be shown to the left of the fieldafterLabel
: [optional, default:"%"
] text that will be shown to the right of the fielddefaultValue
: [optional, default:"95"
] default text before the user enters anythingplaceholderText
: [optional, default:""
] text shown as a placeholder until a user enters something, will not be send to R if left unchanged by the user (mutually exclusive withdefaultValue
)fieldWidth
: [optional, default:40
] in pixels how wide should the field bedecimals
: [optional, default:1
] integer specifying how many decimals the user can enter
Properties:
name
: string identifier (in your R code you will be able to retrieve the value of the field through this identifier)label
: [optional, default:""
] text that will be shown to the left of the fieldafterLabel
: [optional, default:""
] text that will be shown to the right of the fielddefaultValue
: [optional, default:""
] default text before the user enters anythingplaceholderText
: [optional, default:""
] text shown as a placeholder until a user enters something, will not be send to R if left unchanged by the user (mutually exclusive withdefaultValue
)fieldWidth
: [optional, default:40
] in pixels how wide should the field be
For an input with text that can have many lines, use this component. As an Enter
just adds a new line, and thus does not finish the editing, in order to apply the text you entered, you need to type Ctrl-Enter
.
Properties:
title
: [optional, default:""
] title displayed above the TextArea.textType
: [optional, default:""
, values:lavaan
,JAGS
,Rcode
,model
,source
]: this component is in fact often used in a specialized mode, specified by this property):
lavaan
,JAGS
andRcode
: the TextArea is used for Lavaan, JAGS or R code: it gets automatically the right syntax checkmodel
: the TextArea is used as R model.source
: The TextArea can be then used as source for a VariablesList: all unique strings separated by a separator (per default a new line, but can be change via propertyseparator
will be then the terms of the VariablesList.
separtor
,separators
: [optional, default:"\n"
] string or array of strings used to split the string of asource
TextArea
Most analyses are performed on variables. JASP offers a few ways of visualizing these variables in the input form. The general idea is that you get a field of available variables (taken from the dataset) and then one or more fields that the variables can be dragged to. Variable fields should be wrapped in a VariablesForm
. This makes it possible to automatically align multiple variable fields and add assign-buttons.
Properties
name
: identifier of the variables list, this is never send to Rlabel
: [optional, default:""
] text that will be shown above the variable fieldsource
: [optional, default:""
] this can be set to thename
(or a list of names) of anAssignedVariablesList
. If no source is specified, then all variables of the loaded file is used as source. To specify several sources, you need to use an array:["source1", "source2"]
. If you have asingleVariable
Variables List as source, it is possible to specify you want thelevels
of the variable. For this uses:source: [{name: "splitby", use: "levels"}]
. If a VariablesList source is itself composed by several kinds of sources, you can discard one of them in this way:source: [{ name: "modelTerms", discard: "covariates" }]
width
: [optional, default: 2/5 of the VariablesForm width] in pixels how wide should the field be
Note: height
should be defined on VariablesForm
itself.
Examples
VariablesForm
{
AvailableVariablesList { name: "allVariables" }
AssignedVariablesList { name: "fixedFactors"; label: qsTr("Fixed Factors"); allowedColumns: ["ordinal", "nominal"] }
}
VariablesForm
{
height: 200
AvailableVariablesList { name: "postHocTestsAvailable"; source: "fixedFactors" }
AssignedVariablesList { name: "postHocTestsVariables" }
}
Properties
-
name
: identifier of the particular variable field (in your R code you will be able to retrieve the assigned variable(s) through this identifier) -
label
: [optional, default:""
] text that will be shown above the variable field -
columns
: [optional, default: 1] number of columns of the list. -
allowedColumns
: [optional, default: empty, possible values:["scale", "ordinal", "nominal"]
] array specifying the allowed column types -
suggestedColumns
: [optional, default: empty, possible values:["scale", "ordinal", "nominal"]
] array specifying the suggested column types. These types will be displayed as icons at the bottom-right of the AssignedVariablesList. IfsuggestedColumns
is empty andallowedColumns
is specified, thensuggestedColumns
get automatically the value ofallowedColumns
. IfallowedColumns
is empty andsuggestedColumns
is specified, then the following rules apply:scale
allows Nominal Integer and Ordinal columnsnominal
allows all Nominal columns (Integer or String), and Ordinal column- if no
suggestedColumns
and noallowedColumns
is specified, then all types of columns are allowed
-
maxRows
: [optional, default:-1
] maximum number of rows the list can accept. -1 means no limit. -
singleVariable
: [optional, default:false
] if true, set the maxRows to 1 -
listViewType
: [optional] enumerative that specifies the type ofAssignedVariablesList
, when omitted we get a normal list, options areJASP.Layers
(see Contingency Tables),JASP.Interaction
(see ANOVA) andJASP.RepeatedMeasures
(see Repeated Measures ANOVA) -
addInteractionsByDefault
: [optional, default:true
] Specify if all interactions between factors should be automatically added to the model. Only has an effect iflistViewType == JASP.Interaction
. -
width
: [optional, default: 2/5 of the VariablesForm width] in pixels how wide should the field be -
height
: [optional] in pixels how heigh should the field be. Per default, it is set so that all AssignedVariablesList's fit the VariablesForm. If you set the height for 1 AssignedVariablesList, it will try to set height of the other AssignedVariablesLists's so that they all fit the heigth of the VariablesForm. -
count
: [read-only integer] Gives the number of rows of the list. -
rowComponentsLabels
: [optional, default empty array]: array of labels used for rowComponents. -
rowComponents
: It is possible to add one or more components (a CheckBox or a DropDown for example) for each assigned variable. To do this, add therowComponents
property with a list of components you want to add:rowComponents: [ Component { CheckBox { name: "enableNumber"; checked: true } }, Component { DoubleField { name: "myNumber"; defaultValue: rowIndex; enabled: fromRowComponents["enableNumber"].checked } } ]
```
You can use so-called context properties in the components:
- rowIndex: gives the row number in the list
- rowValue: gives the name of the variable in the same row
- colIndex: gives the column number in the corresponding row
- fromRowComponents["`name`"]: gives the component with corresponding name in the same row. See example above.
Examples
VariablesForm
{
AvailableVariablesList { name: "allVariables" }
AssignedVariablesList
{
name: "dependent"
label: qsTr("Dependent Variable")
allowedColumns: ["scale"]
singleVariable: true
}
}
}
VariablesForm
{
AvailableVariablesList { name: "allVariables" }
AssignedVariablesList
{
name: "modelTerms"
label: qsTr("Model terms")
listViewType: JASP.Interaction
rowComponentsLabels: ["Add to null model"]
rowComponents:
[
Component
{
CheckBox { name: "isNuisance" }
}
]
}
}
Properties
name
: identifier of the particular variable field (in your R code you will be able to retrieve the assigned variable(s) through this identifier)label
: [optional, default:""
] text that will be shown above the variable fieldwidth
: [optional, default: ±230
] in pixels how wide should the field beheight
: [optional, default:350
] in pixels how heigh should the field be
Examples
VariablesForm
{
RepeatedMeasuresFactorsList
{
name: "repeatedMeasuresFactors"
label: qsTr("Repeated Measures Factors")
height: 180
}
AssignedVariablesList
{
name: "repeatedMeasuresCells"
label: qsTr("Repeated Measures Cells")
allowedColumns: ["scale"]
listViewType: JASP.MeasuresCells
source: "repeatedMeasuresFactors"
height: 140
}
}
InputListView and TableView are 2 components that allow to view a variable number of input
This component allows the user to specify as many input values as he/she wants. Properties
name
: identifier of this component (in your R code you will be able to retrieve the text value(s) through this identifier)label
: [optional, default:""
] text that will be shown above this componentplaceHolder
: [optional, default"New Value"
] text that is displayed as long as the user did not give a value. When a value is given a new input is then automatically added.defaultValues
: [optional, default empty array] array of strings setting the first value(s) if the input controls.minRows
: [optional, default 0] Minimum of rows the list view should display. No delete icon will be then displayed to these rows.inputComponent
: [optional, default a TextField component] Per default the input field is a TextField component, but you may change this by setting a DoubleField of an IntegerField component.rowComponents
: As for AssignedVariablesList, it is possible to add other components.rowComponentsLabels
: [optional, default empty array] array of labels used for rowComponents.optionKey
: [optional, default"value"
] when using rowComponents, thename
property indicates the name to use to retrieve all values of this component. These values are specified per row, and each row has different columns. The names of the rowComponents are used to specify the value of each component. TheoptionKey
speficies then the name of the value of the Input field.
Example
InputListView
{
name : "groupNames"
title : qsTr("Group name")
optionKey : "group"
defaultValues : ["Group 1", "Group 2"]
placeHolder : qsTr("New Group")
minimumItems : 2
rowComponentsLabels : [qsTr("Group color")]
rowComponents:
[
Component
{
DropDown
{
name: "groupColors"
values: ["red", "blue", "yellow", "green", "purple", "orange"]
}
}
]
}
This component presents the input fields in a Table format.
Properties
name
: identifier of this component (in your R code you will be able to retrieve the text value(s) through this identifier)modelType
: [required, must be eitherMultinomialChi2Model
,JAGSDataInputModel
,FilteredDataEntryModel
orCustomContrasts
] Specify which kind of TableView is used.colName
: [optional, defaultdata
]: name of the generated column whenmodelType
isListModelFilteredDataEntry
orCustomContrasts
itemType
: [optional, defaultstring
, can be alsodouble
orinteger
]tableType
: [optional, defaultExpectedProportions
, can be alsoPriorCounts
]source
: [optional, default ``] source of the values the table is based on
Example
TableView
{
modelType : "MultinomialChi2Model"
itemType : "ExpectedProportions"
tableType : "double"
source : "factor"
}
In order to add more structure to the input panel you can group components together. There are 2 levels of grouping: Section and Group. A Section can hide a group of components under a button. A Group is a smaller logical unit.
Properties
title
: text shown above the grouped input componentscolumns
: [optional, default:1
] integer specifying how many columns the grouped components should occupy
Examples
Group
{
title: qsTr("Output")
CheckBox
{
name: "effects"; label: qsTr("Effects")
RadioButtonGroup
{
name: "effectsType"
RadioButton { value: "allModels"; label: qsTr("Across all models"); checked: true }
RadioButton { value: "matchedModels"; label: qsTr("Across matched models") }
}
}
CheckBox { name: "descriptives"; label: qsTr("Descriptives") }
}
A Section sets components (or groups of components) under a button. By clicking the button, you can hide or display these components. Properties
title
: text shown in the button that controls the collapse of an entire sectioncolumns
: [optional, default:2
] integer specifying how many columns the grouped components should occupy
Examples
Section
{
title: qsTr("Advanced Options")
RadioButtonGroup
{
title: qsTr("Missing Values")
name: "missingValues"
RadioButton { value: "excludeCasesListwise"; label: qsTr("Exclude cases listwise"); checked: true }
RadioButton { value: "excludeCasesPairwise"; label: qsTr("Exclude cases pairwise") }
}
Group
{
title: qsTr("Confidence Interval")
enabled: chronbach.checked
CheckBox
{
name: "confAlpha"
label: qsTr("Cronbach's α analytical")
PercentField { name: "confAlphaLevel"; label: qsTr("Confidence"); defaultValue: 95 }
}
}
}
By default JASP creates a two column grid that is filled row-wise. So each component you place in your QML file will be added to the input panel left to right, top to bottom. We will demonstrate what this means by the use of a table.
Imagine a simple table with two columns and two rows. We have three components (CheckBox A, B and C) and each must go in their own cell. When these components are added row-wise we get A in the top left cell, then next to it B and on its own row C:
<column 1> | <column 2> | |
---|---|---|
<row 1> | CheckBox A | CheckBox B |
<row 2> | CheckBox C |
The above works great, but it definitely helps that the checkboxes are the same size. We could also add a RadioButtonGroup that is much taller than a simple checkbox. If we again imagine three components (but this time CheckBox A and B and RadioButtonGroup A) that go in the table in the same way:
<column 1> | <column 2> | |
---|---|---|
<row 1> | CheckBox A | RadioButtonGroup A |
RadioButtonGroup A | ||
<row 2> | CheckBox B |
We notice that there is a lot of space between CheckBox A and CheckBox B. The reason for this is that CheckBox B is placed in the next available row. Fortunately we can remedy this with the property Layout.rowSpan
; all we need to do is set Layout.rowSpan: 2
in RadioButtonGroup A. This tells the engine that the component spans two rows and therefore CheckBox B will fit snuggly under CheckBox A:
<column 1> | <column 2> | |
---|---|---|
<row 1> | CheckBox A | RadioButtonGroup A |
<row 2> | CheckBox B | RadioButtonGroup A |
Now imagine we really wanted to put the RadioButtonGroup in the top left cell and the two checkboxes below it on the same height as one another:
<column 1> | <column 2> | |
---|---|---|
<row 1> | RadioButtonGroup A | |
RadioButtonGroup A | ||
<row 2> | CheckBox A | CheckBox B |
However, if we simply added the components we would end up with this situation:
<column 1> | <column 2> | |
---|---|---|
<row 1> | RadioButtonGroup A | CheckBox A |
RadioButtonGroup A | ||
<row 2> | CheckBox B |
To accomplish this we can set Layout.columnSpan: 2
on RadioButtonGroup A. This results in the following situation:
<column 1> | <column 2> | |
---|---|---|
<row 1> | RadioButtonGroup A | RadioButtonGroup A |
RadioButtonGroup A | RadioButtonGroup A | |
<row 2> | CheckBox A | CheckBox B |
In AvailableVariablesList
we showed that through its source
property, we can establish a link between two components. There are other ways of connecting components and they are not limited to a VariableList
(although they are a little different, only a VariableList
uses the name
property). QML allows us to do this is by adding an id
to one component and then referencing this id
in a different component. Note that the id
can be any string starting with a lowercase, but it must be unique.
An example is enabling a checkbox if one of two different checkboxes is checked.
Implementation
CheckBox { name: "checkboxA"; label: qsTr("Some label"), id: checkA}
CheckBox { name: "checkboxB"; label: qsTr("Some label"), id: checkB}
CheckBox { name: "checkboxC"; label: qsTr("Some Label too"); enabled: checkA.checked || checkB.checked }
Here we make use of a JavaScript expression to evaluate if either CheckBox A or CheckBox B has been checked and if this is the case we enable CheckBox C. This JavaScript expression will be automatically updated each time that the checked values of checkA and checkB changes.
Another example would be setting the visibility of some textfield to invisible if a checkbox is not checked.
Implementation
CheckBox
{
name: "checkboxA"
label: qsTr("Some label")
id: checkA
TextField { name: "textfieldA"; afterlabel: qsTr("x"); visible: checkA.checked}
}
Any property can be set with an expression. A title of a Section for example:
Implementation
DropDown
{
id: estimator
name: "estimator"
label: qsTr("Estimator")
values: ["EBICglasso", "cor", "pcor", "IsingFit", "IsingSampler", "huge", "adalasso", "mgm"]
}
Section
{
title: qsTr("Analysis Options - ") + estimator.currentText
....
}
We'll create a simple analysis input panel to show the workflow. Read first the Guide to adding a module in JASP. In this way, when you edit your QML file, the changes made will be automatically seen in JASP. You can play with the components and their properties, and see immediately the output in JASP.
We can begin actual work on the QML file, first we have to tell the engine where to find our resources. To do so, we add a number of imports to the top of our file.
Code
import QtQuick 2.11
import QtQuick.Layouts 1.3
import JASP.Controls 1.0
import JASP.Widgets 1.0
At this point we add a Form
which will hold all our input components:
Code
import QtQuick 2.11
import QtQuick.Layouts 1.3
import JASP.Controls 1.0
import JASP.Widgets 1.0
Form
{
}
It's now a matter of mixing and matching the previously shown components to create a form to our liking. Of course, if something isn't quite possible, you can also use QML features that were not covered here.
Code
import QtQuick 2.11
import QtQuick.Layouts 1.3
import JASP.Controls 1.0
import JASP.Widgets 1.0
Form
{
VariablesForm
{
AssignedVariablesList { name: "variables"; allowedColumns: ["ordinal", "nominal"] }
}
RadioButtonGroup
{
Layout.rowSpan: 2
name: "hypothesis"
title: qsTr("Hypothesis")
RadioButton { value: "notEqualToTestValue"; label: qsTr("≠ Test value"); checked: true }
RadioButton { value: "greaterThanTestValue"; label: qsTr("> Test value") }
RadioButton { value: "lessThanTestValue"; label: qsTr("< Test value") }
}
DoubleField { name: "testValue"; label: qsTr("Test value: "); defaultValue: 0.5 ; max: 1; decimals: 2}
Group
{
title: qsTr("Plots")
CheckBox
{
name: "descriptivesPlots"
label: qsTr("Descriptive plots")
PercentField { name: "descriptivesPlotsConfidenceInterval"; label: qsTr("Confidence Interval"); defaultValue: 95 }
}
}
}
QML is a very flexible format, besides giving you access to all of the built-in components and our JASP-components that are detailed under components you can also add your own components! If you add a qml-file to the qml directory, for instance Example.qml
, then it will be treated as a component by all other files in the directory. Make sure to give the file an actual capital as first letter though, otherwise qml will not see it as a component. Then you can use it in another qml file simply by adding Example { id: yourExampleComponent }
and set any of the properties the root-component of your component if desired.
This will give you the opportunity to create reusable parts, for instance, each of your analyses might share a common core. You could add this to a Core.qml
and then this could be part of each analysis and be exactly the same everywhere. If you then also make sure to have a common function in R that uses the options specified in the Core.qml
-component you can reuse that as well.
The possibilities here are rather extended and possibly even endless. See the Qt QML tutorials or the official documentation for more information on this.