QML
← All components

Slider

Choose a number or numeric range by moving one or two handles along a track.

import Syidax.Core.Slider

Supported QML types

TypeDefinition / role
Draggable track for selecting a number or numeric range.

Learn by example

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

01 Basic composition

SySlider is a form field with a rail and a thumb: value moves between min and max on the step grid by click, drag or keyboard.

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: "Volume"
        property real value: 40
        property real min: 0
        property real max: 100
        property real step: 1
        property string showTooltip: "default"
        property string tooltipPlacement: "top"
        property bool reverse: false
        property bool hideTrackFill: false
        property bool disabled: false
        property bool readonly: false
    }

    

    SySlider {
        width: 320
        label: storyArgs.label
        value: storyArgs.value
        min: storyArgs.min
        max: storyArgs.max
        step: storyArgs.step
        showTooltip: storyArgs.showTooltip
        tooltipPlacement: storyArgs.tooltipPlacement
        reverse: storyArgs.reverse
        hideTrackFill: storyArgs.hideTrackFill
        disabled: storyArgs.disabled
        readonly: storyArgs.readonly
        onValueChanged: if (storyArgs.value !== value) storyArgs.value = value
    }

}

02 range · rangeValue

range: true shows two thumbs.

Qt capture · image
range · rangeValue · 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: 16
        SySlider {
            id: price
            width: 320
            label: "Price range"
            range: true; rangeValue: [20, 80]; showTooltip: "always"
        }
        Text { text: price.lo + " – " + price.hi; font.family: Theme.monoFontFamily; font.pixelSize: 12; color: Theme.semantic.textSubtle }
    }
}

03 marks · snapToMarks · hideMarks

marks is an object { value: "label" } — write it as ({ 25: "25%" }) in QML.

Qt capture · image
marks · snapToMarks · hideMarks · Default
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

    property QtObject settings: QtObject {
        id: storyArgs
        property bool snapToMarks: true
        property bool hideMarks: false
    }

    

    SySlider { id: featureTarget0;
        width: 320
        label: "Brightness"
        value: 50
        marks: ({ 0: "0%", 25: "25%", 50: "50%", 75: "75%", 100: "100%" })
        snapToMarks: storyArgs.snapToMarks
        hideMarks: storyArgs.hideMarks
    }
}

04 showTooltip · tooltipPlacement

showTooltip decides when the value bubble appears next to a thumb: "default" shows it while that thumb is hovered or dragged, "always" keeps it visible, "never" hides it.

Qt capture · image
showTooltip · tooltipPlacement · Default
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

    property QtObject settings: QtObject {
        id: storyArgs
        property string showTooltip: "always"
        property string tooltipPlacement: "top"
    }

    

    Item {
        width: 360
        height: 80
        SySlider { id: featureTarget0; x: 20; y: 32; width: 320; value: 60; showTooltip: storyArgs.showTooltip; tooltipPlacement: storyArgs.tooltipPlacement }
    }
}

05 vertical · length

vertical: true turns the rail upright: min sits at the bottom and the value grows upward (the other way round with reverse).

Qt capture · image
vertical · length · 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

    Row {
        spacing: 48
        SySlider { id: featureTarget0; vertical: true; length: 160; value: 30 }
        SySlider { id: featureTarget1; vertical: true; length: 160; value: 70; marks: ({ 50: "half" }); showTooltip: "always"; tooltipPlacement: "right" }
    }
}

06 disabled · readonly · reverse · hideTrackFill

disabled draws the disabled tones and ignores the pointer and Tab focus; readonly keeps the normal rail but the thumb does not move either, by pointer or by key (the arrows included)

Qt capture · image
disabled · readonly · reverse · hideTrackFill · 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: 16
        SySlider { label: "Disabled";  id: featureTarget0; visible: true; width: 320; value: 40; disabled: true }
        SySlider { label: "Read only";  id: featureTarget1; visible: true; width: 320; value: 40; readonly: true }
        SySlider { label: "Reverse";  id: featureTarget2; visible: true; width: 320; value: 40; reverse: true }
        SySlider { label: "No track fill";  id: featureTarget3; visible: true; width: 320; value: 40; hideTrackFill: true }
    }
}

07 changed

changed(detail) is the slider's only signal.

Qt capture · image
changed · 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

    

    Column {
        spacing: 16
        SySlider { id: exampleControl1; 
            width: 320
            label: "Volume"; value: 30; step: 5
            onChanged: (detail) => output.log(("value: %1").arg(detail.value))
        }
        SySlider {
            width: 320
            label: "Price range"; range: true; rangeValue: [20, 80]
            onChanged: (detail) => output.log(("range: %1 – %2").arg(detail.min).arg(detail.max))
        }
        EventLog { id: output }
    }
}

08 getValue

getValue() returns the current number in single mode — clamped into min … max — or { min, max } in range mode; it is the same value the owning form submits.

Qt capture · image
getValue · 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

    Column {
        spacing: 16
        SySlider { id: volume; width: 320; label: "Volume"; value: 30 }
        SySlider { id: price; width: 320; label: "Price range"; range: true; rangeValue: [20, 80] }
        Row {
            spacing: 8
            SyButton { id: exampleControl1;  text: "volume.getValue()"; variant: "secondary"; size: "small"; onClicked: output.log("getValue() → " + JSON.stringify(volume.getValue())) }
            SyButton { id: exampleControl2;  text: "price.getValue()"; variant: "secondary"; size: "small"; onClicked: output.log("getValue() → " + JSON.stringify(price.getValue())) }
            SyButton { id: exampleControl3;  text: "volume.setFocus()"; variant: "secondary"; size: "small"; onClicked: volume.setFocus() }
        }
        EventLog { id: output }
    }
}

API 87

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

Properties

ItemBehavior / conditions
Own properties of SySlider:

Properties

PropertyTypeDefaultDescription
var (number)0The value in single mode. Drawn clamped into min … max; user moves snap to step, code assignments do not. Every change after creation emits changed.
real0The ends of the scale.
real100The ends of the scale.
real1The grid user moves snap to (counted from min, rounded to the step's decimals). 0 disables the grid; the keys then move by 1.
boolfalseTwo thumbs over rangeValue; changed and getValue() switch to { min, max }; value is ignored.
list[][low, high] for range mode; an empty list means [min, max]. Setting it from code emits changed.
object({}){ value: "label" } — a dot and a label per entry inside the scale; min and max are always labelled.
boolfalseHides the dots and labels; snapping to marks still works.
boolfalseUser moves land on the nearest mark instead of the step grid.
string"default"default (while hovered or dragged) · always · never.
string"top"top · bottom · left · right of the thumb.
boolfalseThe rail runs upward over length px; marks sit to the right.
real160The rail length when vertical; ignored otherwise (the width rules).
boolfalsemax at the left / bottom; the fill runs from the max end.
boolfalseNo filled part on the rail.
boolfalseThe thumb does not move on user input; normal tones.
string"single"Which thumb the keys move: single · min · max. Set automatically by a press; set it to min / max for a range slider driven by keys first.
real (read-only)—The clamped low / high values in range mode (min / max otherwise).
real (read-only)—The clamped low / high values in range mode (min / max otherwise).
real (read-only)—value clamped into the scale.
var (read-only)—What the owning form submits: current, or { min, max } in range mode.
bool (read-only)—The rail has keyboard focus.
bool (read-only)—!disabled && !readonly.

Properties

ItemBehavior / conditions
Inherited from the field frame (SyFieldFrame):

Properties

PropertyTypeDefaultDescription
string""The title above the rail; required adds the asterisk.
string""The key in SyForm.values().
string"medium"Only changes the title's font size here (12 / 14 / 16 px).
boolfalseDisabled tones; the pointer and Tab are ignored; the form skips the field.
boolfalseDraws the asterisk only — the slider is always valid.
string""Helper text under the rail
string""custom error copy (never shown, the slider is always valid).
real240The width when the app sets none.
booltrueThe title line and the gap between title, rail and message.
realsmall spacingThe title line and the gap between title, rail and message.
read-only—Always true · false · "" for a slider.
read-only—Always true · false · "" for a slider.
read-only—Always true · false · "" for a slider.

Methods

MethodDescription
Returns current (a number) in single mode, { min, max } in range mode.
Gives the rail keyboard focus (the keys move activeThumb)
takes it away.
Puts value back to the value at creation and clears the touched / submitted flags. rangeValue is not restored.
Always return true (no validity rules).
Always return true (no validity rules).
Always returns "".
Set / clear the custom-error flag; it has no visible effect on a slider.
Set / clear the custom-error flag; it has no visible effect on a slider.

Signals

SignalArgumentsWhen
detail: { value } (single) or { min, max } (range)Every change of value / rangeValue after creation — pointer, keys or code. Values are clamped. Not for the initial value; user input is blocked while disabled / readonly.
detailDeclared by the field base; the slider never emits them. Use hasFocus.
detailDeclared by the field base; the slider never emits them. Use hasFocus.

Behavior

ItemBehavior / conditions
The value in single mode. Drawn clamped into min … max; user moves snap to step, code assignments do not. Every change after creation emits changed.
value is drawn clamped into min … max (current is that clamped number). User moves snap to the step grid counted from min and rounded to the decimals of step; a step of 0 disables the grid (free movement, keys move by 1). once the rail has focus (Tab reaches it when interactive, a press gives it, setFocus() too): Left / Down move one step down, Right / Up one step up, PageDown / PageUp ten steps, Home to min, End to max. activeThumb starts as "single", which targets no range thumb — set it to "min" or "max" yourself when a range slider must answer to keys before any click. rangeValue: [low, high] positions the two thumbs; an empty list means [min, max]. changed carries { min, max }; getValue() and the form value are the same object. Entries outside min … max are dropped; min and max always get a dot labelled with their number unless you label them. name keys the value in SyForm.values(): the number in single mode, { min, max } in range mode (formValue).
value is drawn clamped into min … max (current is that clamped number). once the rail has focus (Tab reaches it when interactive, a press gives it, setFocus() too): Left / Down move one step down, Right / Up one step up, PageDown / PageUp ten steps, Home to min, End to max. activeThumb starts as "single", which targets no range thumb — set it to "min" or "max" yourself when a range slider must answer to keys before any click. rangeValue: [low, high] positions the two thumbs; an empty list means [min, max]. changed carries { min, max }; getValue() and the form value are the same object. Entries outside min … max are dropped; min and max always get a dot labelled with their number unless you label them. reverse puts max first (left, or bottom when vertical); hideTrackFill removes the filled part between the start (or the low thumb) and the thumb. name keys the value in SyForm.values(): the number in single mode, { min, max } in range mode (formValue).
value clamped into the scale.
The grid user moves snap to (counted from min, rounded to the step's decimals). 0 disables the grid; the keys then move by 1.
Every change of value / rangeValue after creation — pointer, keys or code. Values are clamped. Not for the initial value; user input is blocked while disabled / readonly.
a press on the rail jumps the nearest thumb (the only thumb in single mode) to the pointer and focuses the rail; dragging follows the pointer until release. Hovering a thumb shows the tooltip in the "default" mode; hovering the rail switches it to the hover tones.
once the rail has focus (Tab reaches it when interactive, a press gives it, setFocus() too): Left / Down move one step down, Right / Up one step up, PageDown / PageUp ten steps, Home to min, End to max.
Which thumb the keys move: single · min · max. Set automatically by a press; set it to min / max for a range slider driven by keys first.
In range mode the keys move activeThumb: a press sets it to the thumb it moved, and Home / End stop at the other thumb (lo for the high thumb, hi for the low one). lo and hi are the clamped pair at all times.
In range mode the keys move activeThumb: a press sets it to the thumb it moved, and Home / End stop at the other thumb (lo for the high thumb, hi for the low one). lo and hi are the clamped pair at all times. A thumb never passes the other: dragging the low thumb past the high one parks it at hi, and vice versa.
[low, high] for range mode; an empty list means [min, max]. Setting it from code emits changed.
Returns current (a number) in single mode, { min, max } in range mode.
Disabled tones; the pointer and Tab are ignored; the form skips the field.
The thumb does not move on user input; normal tones.
focused / blured exist on the field base but the slider does not emit them — read hasFocus.
focused / blured exist on the field base but the slider does not emit them — read hasFocus.
The rail has keyboard focus.
{ value: "label" } — a dot and a label per entry inside the scale; min and max are always labelled.
The title above the rail; required adds the asterisk.
User moves land on the nearest mark instead of the step grid.
Hides the dots and labels; snapping to marks still works.
default (while hovered or dragged) · always · never.
top · bottom · left · right of the thumb.
The width when the app sets none.
Horizontal: the rail spans the field's width — preferredWidth 240 unless the app sets width — and the field is 14 px tall plus 24 px when marks show plus the tooltip inset; the label sits above and message below, like every field.
Horizontal: the rail spans the field's width — preferredWidth 240 unless the app sets width — and the field is 14 px tall plus 24 px when marks show plus the tooltip inset; the label sits above and message below, like every field.
The rail length when vertical; ignored otherwise (the width rules).
max at the left / bottom; the fill runs from the max end.
No filled part on the rail.
The key in SyForm.values().
name keys the value in SyForm.values(): the number in single mode, { min, max } in range mode (formValue).
What the owning form submits: current, or { min, max } in range mode.
The slider has no validity rules: checkValidity() / reportValidity() return true, getStatus() returns "", and required only draws the asterisk in the title.
The slider has no validity rules: checkValidity() / reportValidity() return true, getStatus() returns "", and required only draws the asterisk in the title.
Always returns "".
Draws the asterisk only — the slider is always valid.