QML
← All components

Switch

Toggle a setting between on and off, such as notifications or automatic saving.

import Syidax.Core.Switch

Supported QML types

TypeDefinition / role
On/off form field styled as a sliding switch.

Learn by example

Previews are images of native Qt runs. Use the buttons below each image to view a result.

01 Basic composition

SySwitch is the on / off toggle: a track with a sliding handle and the label beside it.

Qt capture · image
Basic composition · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    property QtObject settings: QtObject {
        id: storyArgs
        property string label: "Notifications"
        property bool checked: true
        property string size: "medium"
        property bool loading: false
        property bool disabled: false
        property bool readonly: false
        property bool required: false
    }

    

    SySwitch {
        label: storyArgs.label
        checked: storyArgs.checked
        size: storyArgs.size
        loading: storyArgs.loading
        disabled: storyArgs.disabled
        readonly: storyArgs.readonly
        required: storyArgs.required
        onCheckedChanged: if (storyArgs.checked !== checked) storyArgs.checked = checked
    }

}

02 size

size has two values: medium (the default) draws a 44 × 22 px track with an 18 px handle, small a 28 × 16 px track with a 12 px handle; the "|" and "○" marks on the track and the loading ring scale with it.

Qt capture · image
size · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    Column {
        spacing: 12
        SySwitch { label: "Notifications"; checked: true }
        SySwitch { label: "Notifications"; checked: true; size: "small" }
    }
}

03 loading

Compare the configuration and result of loading.

Qt capture · image
loading · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    Column {
        spacing: 12
        SySwitch {
            id: sync
            label: "Sync in the background"
            onChanged: (checked) => { loading = true; saveTimer.restart() }
        }
        Timer { id: saveTimer; interval: 1500; onTriggered: sync.loading = false }
        SySwitch { label: "Saving…"; checked: true; loading: true }
        SySwitch { label: "Saving…"; loading: true; size: "small" }
    }
}

04 disabled · readonly

disabled: true grays the track and the label and makes the switch inert: no click, no keys, Tab skips it, the arrow cursor.

Qt capture · image
disabled · readonly · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    Column {
        spacing: 12
        SySwitch { id: featureTarget0; visible: true; label: "Disabled"; disabled: true }
        SySwitch { id: featureTarget1; visible: true; label: "Disabled"; disabled: true; checked: true }
        SySwitch { id: featureTarget2; visible: true; label: "Read only"; readonly: true }
        SySwitch { id: featureTarget3; visible: true; label: "Read only"; readonly: true; checked: true }
    }
}

05 changed

The switch has three signals, all carrying the current checked boolean rather than an object.

Qt capture · image
changed · Default
Default execution
QML code
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "Interact with the controls to see event results."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height

    

    Column {
        spacing: 12
        SySwitch {
            label: "Dark mode"
            onChanged: (checked) => output.log(("changed: %1").arg(checked))
        }
        EventLog { id: output }
    }
}

06 toggle · setFocus · checkValidity · …

The switch's functions, shown by the buttons in the demo (a required Notifications switch):

Qt capture · image
toggle · setFocus · checkValidity · … · Default
QML code
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "Interact with the controls to see event results."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    Column {
        spacing: 12
        SySwitch { id: notify; label: "Notifications"; required: true }
        Flow {
            width: 560
            spacing: 8
            SyButton { id: exampleControl1;  visible: true; text: "notify.toggle()"; variant: "secondary"; size: "small"; onClicked: notify.toggle() }
            SyButton { id: exampleControl2;  visible: true; text: "notify.setFocus()"; variant: "secondary"; size: "small"; onClicked: notify.setFocus() }
            SyButton { id: exampleControl3;  visible: true; text: "notify.checkValidity()"; variant: "secondary"; size: "small"; onClicked: output.log("checkValidity() → " + notify.checkValidity()) }
            SyButton { visible: true; text: "notify.reportValidity()"; variant: "secondary"; size: "small"; onClicked: output.log("reportValidity() → " + notify.reportValidity()) }
            SyButton { visible: true; text: "notify.getValidStatus()"; variant: "secondary"; size: "small"; onClicked: output.log("getValidStatus() → " + JSON.stringify(notify.getValidStatus())) }
        }
        EventLog { id: output }
    }
}

07 Required field and reset

Compare the untouched field, validation error and reset result.

Qt capture · image
Required field and reset · Untouched
QML code
import QtQuick
import Syidax.Core

Column {
    width: 440; spacing: 12
    SySwitch {
        id: field; width: parent.width; name: "selection"; required: true
        label: "Required selection"
        
        error: "Complete this field before continuing."
    }
    Row {
        spacing: 8
        SyButton { id: check; text: "Validate"; onClicked: field.reportValidity() }
        SyButton { id: reset; text: "Reset"; onClicked: field.reset() }
    }
    Text { text: "Status: " + (field.invalid ? "Invalid" : "Ready"); color: Theme.semantic.textDefault }
}

08 Custom error

Show an application-specific error, then reset the field.

Qt capture · image
Custom error · Untouched
QML code
import QtQuick
import Syidax.Core

Column {
    width: 440; spacing: 12
    SySwitch {
        id: field; width: parent.width; name: "selection"; required: true
        label: "Required selection"
        checked: true
        error: "This selection is currently unavailable. Choose another."
    }
    Row {
        spacing: 8
        SyButton { id: check; text: "Show error"; onClicked: field.setCustomError() }
        SyButton { id: reset; text: "Reset"; onClicked: field.reset() }
    }
    Text { text: "Status: " + (field.invalid ? "Invalid" : "Ready"); color: Theme.semantic.textDefault }
}

API 73

Hover or select an item for its QML example and copy button.

Properties

ItemBehavior / conditions
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.
The shared field properties (name, required, disabled, message, error, touched, submitted, customError, validStatus, valid, invalid, ready) are described on the Form page; the ones below are the switch's own or have switch-specific meaning.

Properties

PropertyTypeDefaultDescription
boolfalseThe state. Flipped by a click on the track, Space / Enter and toggle(); every change emits changed.
string""The text beside the track, with * when required. Hidden when empty.
string"medium"medium (44 × 22 px) · small (28 × 16 px). Any other value draws medium.
boolfalseSpinner in the handle; the switch ignores every flip until it is cleared. Does not change checked.
string"on"What the owning SyForm submits under name while on.
var (read-only)—value while on, null otherwise — what SyForm.values() stores.
string""Key in the owning SyForm's values().
boolfalseOff → valueMissing; adds the * mark.
boolfalseInert and grayed; not a Tab stop; always valid; not submitted.
boolfalseFocusable but unchangeable; always valid; still submitted.
string""Helper line under the switch
string""custom error copy for the required check.
bool (read-only)—The track has active focus
bool (read-only)—the pointer is over it (false while disabled)
bool (read-only)—it is being pressed.
bool (read-only)—Not disabled, not read-only, not loading — a flip is possible.
read-only—The geometry for the current size.
read-only—The geometry for the current size.
read-only—The geometry for the current size.
read-only—The geometry for the current size.
string (read-only)—enabled · hover · focus · pressed · loading · readonly · disabled.
boolfalseThe field base's title line, turned off for the switch (the label sits beside the track).

Methods

MethodDescription
The click: flips checked (changed fires). Ignored while disabled, readonly or loading.
Give the track keyboard focus / take it away (focused / blured fire; the blur sets touched).
Give the track keyboard focus / take it away (focused / blured fire; the blur sets touched).
true unless a required switch is off (or a custom error is set). Silent.
Same verdict, and the error line shows from now on.
"" · valueMissing · custom.
"" · valueMissing · custom.
Force / lift the custom status; the error shows at once.
Force / lift the custom status; the error shows at once.
Restores checked (to initialChecked, the value the switch was created with) and value, and clears the touched, reported and custom flags.

Signals

SignalArgumentsWhen
checked: bool — the new statechecked changed after load, by the user or from code. Not for the initial value; not while disabled, read-only or loading block the flip.
checked: bool — the current stateThe track gained active focus.
checked: bool — the current stateThe track lost focus; touched is set first.

Behavior

ItemBehavior / conditions
The state. Flipped by a click on the track, Space / Enter and toggle(); every change emits changed.
The click: flips checked (changed fires). Ignored while disabled, readonly or loading.
checked changed after load, by the user or from code. Not for the initial value; not while disabled, read-only or loading block the flip.
Spinner in the handle; the switch ignores every flip until it is cleared. Does not change checked.
What the owning SyForm submits under name while on.
value while on, null otherwise — what SyForm.values() stores.
Key in the owning SyForm's values().
Off → valueMissing; adds the * mark.
required makes an off switch valueMissing; the error line under the switch ("This field is required", or error) appears once the switch was left (touched) or reported (submitted).
required makes an off switch valueMissing; the error line under the switch ("This field is required", or error) appears once the switch was left (touched) or reported (submitted).
required makes an off switch valueMissing; the error line under the switch ("This field is required", or error) appears once the switch was left (touched) or reported (submitted).
message draws a helper line under it.
Inert and grayed; not a Tab stop; always valid; not submitted.
Focusable but unchangeable; always valid; still submitted.
Tab stops on the track unless it is disabled (a read-only switch is still a Tab stop); Space, Return and Enter toggle. The focus ring is drawn 2 px outside the track while it has focus and is not disabled. The hand cursor shows while the switch is interactive (not disabled, read-only or loading).
The handle slides in 200 ms and the track color cross-fades in 200 ms; while the track is pressed the handle stretches into a pill (6 px wider, 4 px when small) and springs back on release. All of it is skipped under Theme.reducedMotion.
disabled grays everything, blocks every interaction and the Tab stop, and the switch is skipped by SyForm.values().
Tones: disabled > readonly > loading > pressed > focus > hover > enabled, in the checked or unchecked palette.
Tones: disabled > readonly > loading > pressed > focus > hover > enabled, in the checked or unchecked palette.
Tones: disabled > readonly > loading > pressed > focus > hover > enabled, in the checked or unchecked palette.
The track gained active focus.
The track lost focus; touched is set first.
medium (44 × 22 px) · small (28 × 16 px). Any other value draws medium.
size is medium (44 × 22, handle 18) or small (28 × 16, handle 12); the label is 14 px in both.
The text beside the track, with * when required. Hidden when empty.
Colors come from Theme.switchFamily by state and follow Theme.scheme; the handle is the page background color.