Skip to content
Selection controls

Selection controls

Selection controls let the user choose instead of type. Each one reports the choice through an OnChanged function and keeps it in an exported field you can read at any time.

Which one to use

You want the user toUse
Agree to one thing, or turn one option onCheck
Turn a setting on or off that applies at onceSwitch
Pick any number from a short listCheckGroup
Pick exactly one from a short list, all options visibleRadioGroup
Pick one from a longer list, shown on demandSelect (or SearchSelect for long lists, see Text input)
Pick one of 2 to 5 options shown as buttonsSegmentedButton (see Buttons)
Pick a value along a rangeSlider
Pick a low and high boundRangeSlider
Set an exact number by stepping up and downSpinBox

Check and CheckGroup

terms := widget.NewCheck("I accept the terms", func(on bool) {
	status.SetText(fmt.Sprint("Accepted: ", on))
})

toppings := widget.NewCheckGroup([]string{"Cheese", "Olives", "Basil"}, func(sel []string) {
	status.SetText("Toppings: " + strings.Join(sel, ", "))
})
toppings.Horizontal = true
toppings.SetSelected([]string{"Cheese"})

Check is a check box with a label. Checked holds its state and SetChecked changes it from code (safe from any goroutine). Setting Partial shows a dash, the “some but not all” state of a parent check box. The user cannot set it; a tap on a partial check box checks it. NewCheckWithData connects the check box to a binding.Bool.

CheckGroup shows one check box per option and passes the list of checked options to OnChanged. Horizontal lays them out in a row. With Required set, the user cannot uncheck the last checked option. Append and Remove change the options later.

RadioGroup

size := widget.NewRadioGroup([]string{"Small", "Medium", "Large"}, func(s string) {
	status.SetText("Size: " + s)
})
size.Required = true
size.SetSelected("Medium")

RadioGroup keeps at most one option selected and passes its text to OnChanged. Tapping the selected option again clears the selection, unless Required is set. SetSelected picks an option from code and is safe to call from any goroutine.

Select

lang := widget.NewSelect([]string{"English", "Deutsch", "Français"}, func(s string) {
	status.SetText("Language: " + s)
})
lang.PlaceHolder = "Language"

Select shows the current option and opens the full list when tapped. Until the user picks something it shows PlaceHolder.

  • Selected holds the chosen text. SelectedIndex() returns its position, or -1.
  • SetSelected and SetSelectedIndex choose from code. ClearSelected goes back to the placeholder.
  • SetOptions replaces the list.
  • NewSelectWithData connects the selection to a binding.String.

Switch

wifi := widget.NewSwitch(func(on bool) {
	status.SetText(fmt.Sprint("Wi-Fi: ", on))
})
wifi.On = true

Switch is the MD3 toggle with a sliding thumb. On holds the state and OnChanged receives each change. It has no label of its own, so put a Label next to it. Space toggles a focused switch.

Use a Switch for a setting that takes effect immediately. Use a Check when the choice is applied later, for example when a form is submitted.

Slider

volume := widget.NewSlider(0, 100)
volume.Step = 1
volume.ShowValueIndicator = true
volume.OnChanged = func(v float64) {
	status.SetText(fmt.Sprintf("Volume %.0f", v))
}
volume.OnChangeEnded = func(v float64) {
	status.SetText(fmt.Sprintf("Volume set to %.0f", v))
}
volume.SetValue(40)

rating := widget.NewSlider(1, 5)
rating.Step = 1
rating.ShowTickMarks = true

Slider moves between Min and Max. Step snaps the value; with Step above zero, ShowTickMarks draws a mark at each step. ShowValueIndicator shows the value above the thumb while dragging. Set Orientation to widget.Vertical for an upright slider.

  • OnChanged runs continuously while the user drags. OnChangeEnded runs when the change is finished, for example when the drag ends. Save or send the value in OnChangeEnded.
  • SetValue clamps the value into range and fires both callbacks, as if the user had moved it. SetValueSilently moves the thumb without firing them, for example to show playback position. Both are safe from any goroutine.
  • Dragging() reports whether the user is dragging right now. A media player can use it to stop updating the position while the user scrubs.
  • OnHover and OnHoverEnd report the value under the pointer without moving the thumb, which suits a preview on a seek bar.

NewSliderWithData connects the value to a binding.Float.

RangeSlider

price := widget.NewRangeSlider(0, 500)
price.Step = 10
price.SetValues(100, 300)
price.OnChangeEnded = func(low, high float64) {
	status.SetText(fmt.Sprintf("Price %.0f to %.0f", low, high))
}

RangeSlider has two thumbs. LowValue and HighValue hold the range, and both callbacks receive both values. SetValues clamps, snaps to Step and swaps the values if they arrive the wrong way round; SetValuesSilently does the same without firing the callbacks. From the keyboard, the arrows along the slider move the focused thumb, and the arrows across it switch between thumbs.

SpinBox

guests := widget.NewSpinBox(1, 12, 1)
guests.SetValue(2)
guests.OnChanged = func(v float64) {
	status.SetText(fmt.Sprintf("%.0f guests", v))
}

SpinBox is a number field with increment and decrement buttons. Each press adds or subtracts Step, and SetValue clamps to Min and Max. The up and down arrow keys step the value when it has focus.