QML Best Practices · Ultimaker/Cura Wiki · GitHub
Skip to content

QML Best Practices

Jaime van Kessel edited this page Nov 16, 2022 · 7 revisions

This page provides an overview of the QML best practices for working on Cura, Uranium and plugin interfaces.

Style

Here are the style rules for qml files. Not all of our code conforms to these rules.

Variables

  • Variables should be in camelCase: excellentVariableName
  • When declaring properties be specific as possible about its type: property int counter
  • Prefer assigning variables using single lines over code blocks: color = warning ? "red" : "green"
  • If you are doing the same boolean check on many components, consider using the State Component

Functions

  • Functions should be in camelCase: updateCoolItem()
  • Don't single line functions
function show() {
    opacity = text != "" ? 1 : 0
}

Components

  • Components should be in PascalCase: CoolLabelItem {}
  • Comments should go on the line before a Component name (Same lining breaks QML Jetbrains plugin)
// This text field shows text 
TextField
{
}
  • Braces (Curly Brackets) always go on a new line
  • Use our styled UM components over the base Qt Components
  • id should be the first assigned property in a component, followed by layout changing properties (width, height, anchors, margin, padding)

Theming

We use theme.json files to set the UI theme. All themes inherit from the default light mode theme.json.

Colors

Theme colors should always be used in qml over color names or color hex values.

Example Usage:

color:  UM.Theme.getColor("text_link")

We have a base set of colors inside theme.json under "base_colors". These cover the base colors for backgrounds, accents, text and borders. We have a set of more specific colors under "colors". Many of these point to the base_colors. For example "text_link" points to the base color "accent_1".

"text_link": "accent_1"

You can define new colors for specific element types such as "scrollbar_handles", but new colors should always point to a base color when possible. When in doubt you can reference a base color directly instead of adding to the theme.json.

color:  UM.Theme.getColor("accent_1")

Size

Theme sizes should always be used in qml over raw numbers. If you are using ratios between element sizes, consider using OML Layouts. Sizes are stored in theme.json. You can fetch sizes in QML using the theme object. Make sure to specify .width or .height

Example Usage:

leftPadding: UM.Theme.getSize("default_margin").width

Sizes are stored in theme.json as lists of two items, [width, height].

"machine_selector_widget": [20.0, 4.0]

Fonts

Theme fonts should always be used over defining a font in QML. If you are assigning the "default" font to your element, consider using one of the generic components from UM such as Label.

Example Usage:

font: UM.Theme.getFont("medium")

Helpful for Automated Testing

These are some things that make maintaining our squish tests much easier.

  • When doing a redesign, keep ids the same where possible
  • If the value of a component is dynamic, such as a current material type label, give it an id
  • If there are many generic components being generated dynamically (ListView) give the container an id
  • If a component can be interacted with, such as a button, give it an id.
  • If many generic components are on the same level, such as 5 Labels or 5 Textfields, give them ids.

Extra Bits of Advice

  • Always make sure sizes are rounded to whole pixels, so all items are rendered at whole pixel offsets. Texts that render at fractional offsets can render ugly or broken, depending on system and display configurations. Sizes that are received from UM.Theme.getSize() are rounded to whole pixels by default, but care must be taken with multiplications and divisions of these values. Use Math.floor() to these sizes. Failure to do this will result in strange font weight and kerning.

Example Classes

Using States: TextField

Theming with color, font, and size: ExtruderIcon

Single and Multiline functions: SettingCheckBox

Clone this wiki locally