flet-circular-slider
A circular/radial slider control for Flet, wrapping the sleek_circular_slider Flutter package.
Install
pip install flet-circular-slider
Then register it as a Flet extension in your project's pyproject.toml so the Flutter widget gets compiled:
[project]
dependencies = ["flet-circular-slider>=0.6.0"]
[tool.flet.dev_packages]
flet-circular-slider = ">=0.5.0"
Then run flet build (see Building below). flet run alone won't compile extensions -- you'll get "Unknown control" without a build step.
Quick Start
import flet as ft
from flet_circular_slider import FletCircularSlider
def main(page: ft.Page):
page.bgcolor = "#1a1a2e"
slider = FletCircularSlider(
min=0, max=100, value=25, size=200,
on_change=lambda e: print(int(e.data)),
)
page.add(slider)
ft.run(main)
Programmatic Updates
Set the slider value from Python code -- the widget animates smoothly to the new position:
slider = FletCircularSlider(min=0, max=100, value=25, size=200)
page.add(slider)
# Later, from a timer, another control, or any event:
slider.value = 75
slider.update() # slider animates to 75
This works for dashboards, timers, or any scenario where Python drives the value. See the root main.py demo app for a full showcase with all features.
Label Formatting
Use label_formatter to transform the numeric value into any string. The callback runs once per step at build time, so the slider displays your formatted labels (e.g. "1h 30m") instead of raw numbers.
def format_duration(minutes: float) -> str:
m = int(minutes)
if m == 0:
return "0m"
h, rem = divmod(m, 60)
if h == 0:
return f"{rem}m"
return f"{h}h {rem}m" if rem else f"{h}h"
slider = FletCircularSlider(
min=0, max=200, value=90,
divisions=200,
label_formatter=format_duration,
size=280,
)
divisions is required when using label_formatter -- it controls how many labels are pre-computed and sent to the Flutter side.
Demo app
The root main.py is a comprehensive mobile-friendly demo with 7 sections covering all features: basic usage, styling, duration picker, disabled mode, programmatic updates, cross-slider control, and event logging.
Run it with flet build apk from the project root, or use python build.py for the full build+deploy pipeline.
Examples
Individual examples in examples/:
- basic.py -- Minimal slider with
on_changeevent - advanced.py -- Custom colors, geometry, labels, sizing, and all three events
- duration_picker.py -- Duration picker using
label_formatterto display "1h 30m" style labels - live_dashboard.py -- Full dashboard with auto-animation, controller slider, and colored presets
- feature_demo.py -- Disabled mode, text styling, and multi-color gradients
Properties
| Property | Type | Default | Description |
|---|---|---|---|
min |
float |
0 |
Minimum value |
max |
float |
100 |
Maximum value |
value |
float |
50 |
Initial value |
size |
float |
150 |
Diameter in pixels |
start_angle |
float |
150 |
Arc start angle in degrees clockwise from bottom-left (0-359) |
angle_range |
float |
240 |
Arc total range (degrees) |
counter_clockwise |
bool |
False |
Reverse drag direction |
animation_enabled |
bool |
True |
Animate to initial value |
anim_duration_multiplier |
float |
1.0 |
Animation speed multiplier for value changes |
progress_bar_width |
float |
size/10 |
Progress arc width |
track_width |
float |
bar/4 |
Background track width |
handler_size |
float |
bar/5 |
Drag handle size |
shadow_width |
float |
bar*1.4 |
Shadow ring thickness |
progress_bar_start_color |
ColorValue |
purple | Gradient start color |
progress_bar_end_color |
ColorValue |
pink | Gradient end color |
progress_bar_colors |
list[ColorValue] |
none | Multi-color gradient (overrides start/end) |
track_color |
ColorValue |
light purple | Track color |
dot_color |
ColorValue |
white | Handle dot color |
shadow_color |
ColorValue |
blue | Shadow color |
hide_shadow |
bool |
False |
Remove the shadow |
inner_text_color |
ColorValue |
gradient end | Center text color |
inner_text_size |
float |
auto | Override center text font size |
inner_text_font_weight |
str |
bold |
Center text font weight (e.g. "w300", "bold") |
inner_text_font_family |
str |
none | Center text font family |
top_label_color |
ColorValue |
white70 | Top label text color |
top_label_size |
float |
12 |
Top label font size |
top_label_font_weight |
str |
w600 |
Top label font weight |
top_label_font_family |
str |
none | Top label font family |
bottom_label_color |
ColorValue |
white70 | Bottom label text color |
bottom_label_size |
float |
12 |
Bottom label font size |
bottom_label_font_weight |
str |
w600 |
Bottom label font weight |
bottom_label_font_family |
str |
none | Bottom label font family |
disabled |
bool |
False |
Disable interaction (dims to 50% opacity) |
divisions |
int |
none | Snap reported value and display to N steps (knob tracks continuously) |
change_throttle_ms |
int |
none | Throttle on_change events (milliseconds) |
inner_text |
str |
raw value | Center text ({value} placeholder) |
top_label |
str |
none | Label above center |
bottom_label |
str |
none | Label below center |
label_formatter |
Callable |
none | Callback (float) -> str to format displayed value |
label_map |
dict |
none | Pre-computed {value: label} map (set automatically by label_formatter) |
Events
| Event | e.data |
Description |
|---|---|---|
on_change |
current value (string) | Fires continuously while dragging (see change_throttle_ms to reduce rate) |
on_change_start |
value at drag start (string) | Fires once when drag begins |
on_change_end |
value at drag end (string) | Fires once when drag ends |
e.data is a string. For integer divisions use int(e.data). For continuous (no divisions) or fractional ranges use float(e.data).
Repo structure
├── main.py # demo app (flet build target)
├── build.py # APK build+deploy automation
├── serve_web.py # local web server for flet build web
├── pyproject.toml # demo app config
├── flet_circular_slider/ # library (published to PyPI)
│ ├── pyproject.toml
│ └── src/
│ ├── flet_circular_slider/ # Python control
│ └── flutter/ # Dart/Flutter widget
└── examples/ # standalone examples
Building
Custom Flet extensions require flet build to compile Dart/Flutter code. flet run alone shows "Unknown control" because it uses a pre-built binary.
flet build web # no extra tooling needed
flet build windows # requires Visual Studio C++ workload
flet build apk # Android
flet build macos # macOS
After building, flet run works for Python-only changes. Rebuild when you change Dart code.
License
MIT
Metadata
Release files for flet-circular-slider 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| flet_circular_slider-0.8.0.tar.gz | 10.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| flet_circular_slider-0.8.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.4 kB
Release files / flet_circular_slider-0.8.0.tar.gz
| Download URL | flet_circular_slider-0.8.0.tar.gz |
|---|---|
| Size | 10.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2635233237af9a2f5b939b0e52ecdafdef53cfc0d5a7276895193571c3181eca
|
|
BLAKE2b-256 checksum How to use checksums |
db58ef431a25877617726ed45656b1995f807f694b1de8ee4a3ac43bf97bbde6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / flet_circular_slider-0.8.0-py3-none-any.whl
| Download URL | flet_circular_slider-0.8.0-py3-none-any.whl |
|---|---|
| Size | 12.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
deae85de364eaebfec3650d313f282407e8ccbc4a554f36a10e4503faa609a7f
|
|
BLAKE2b-256 checksum How to use checksums |
40ce7206b2108969345863c7720b3d017fd9a2c28ca46a3d12464794b25621df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|