#gui #bindings #graphics

macro fltk-derive

Rust bindings for the FLTK GUI library

128 releases (9 breaking)

new 0.10.0 Oct 26, 2020
0.9.2 Sep 26, 2020
0.7.25 Jul 29, 2020
0.1.22 Mar 31, 2020

#146 in GUI

Download history 338/week @ 2020-07-09 168/week @ 2020-07-16 442/week @ 2020-07-23 146/week @ 2020-07-30 446/week @ 2020-08-06 226/week @ 2020-08-13 242/week @ 2020-08-20 282/week @ 2020-08-27 654/week @ 2020-09-03 118/week @ 2020-09-10 89/week @ 2020-09-17 159/week @ 2020-09-24 306/week @ 2020-10-01 112/week @ 2020-10-08 333/week @ 2020-10-15 94/week @ 2020-10-22

1,068 downloads per month
Used in 2 crates (via fltk)

MIT license



Documentation Crates.io License Build

Rust bindings for the FLTK Graphical User Interface library.

The FLTK crate is a crossplatform lightweight gui library which can be statically linked to produce small, self-contained and fast gui applications.

Why choose FLTK?

  • Lightweight. Small binary, around 1mb after stripping. Small memory footprint.
  • Speed. Fast to install, fast to build, fast at startup and fast at runtime.
  • Single executable. No dlls to deploy.
  • Supports old architectures.
  • FLTK's permissive license which allows static linking for closed-source applications.
  • Themability (4 supported themes: Base, GTK, Plastic and Gleam).
  • Provides around 80 widgets. Has inbuilt image support.

Here is a list of software using FLTK.

  • Link to the official FLTK repository.
  • Link to the official documentation.


Just add the following to your project's Cargo.toml file:

fltk = "^0.7"

The library offers prebuilt static cfltk and fltk libraries, which can be added using the "fltk-bundled" flag:

fltk = { version = "^0.7", features = ["fltk-bundled"] }

Since these are pre-built libraries using the Github actions CI, the currently supported operating systems are:

  • Windows 10 x64 (msvc and gnu).
  • MacOS 10.15 x64.
  • Ubuntu 18.04 or later, x64.

The library is automatically statically linked to your binary. If however you would prefer dynamic linking, you can use the fltk-shared feature:

fltk = { version = "^0.7", features = ["fltk-shared"] }

You can also enable ninja builds for a faster build of the C++ source using the "use-ninja" feature. Or if you have fltk already installed, you can use the system-fltk feature, but note that this crate uses the latest FLTK (1.40).

To use the master branch in your project, you can use:

fltk = { git = "https://github.com/MoAlyousef/fltk-rs" }

An example hello world application:

use fltk::{app::*, window::*};

fn main() {
    let app = App::default();
    let mut wind = Window::new(100, 100, 400, 300, "Hello from rust");

Another example showing the basic callback functionality:

use fltk::{app::*, button::*, frame::*, window::*};

fn main() {
    let app = App::default();
    let mut wind = Window::new(100, 100, 400, 300, "Hello from rust");
    let mut frame = Frame::new(0, 0, 400, 200, "");
    let mut but = Button::new(160, 210, 80, 40, "Click me!");
    but.set_callback(Box::new(move || frame.set_label("Hello World!")));

Please check the examples directory for more examples. You will notice that all widgets are instantiated with a new() method, taking the x and y coordinates, as well as the width and height of the widget. Most widgets, except the TextDisplay and TextEditor, also take a label which can be left blank if needed. Another way to initialize a widget is using the builder pattern: (The following buttons are equivalent)

let but1 = Button::new(10, 10, 80, 40, "Button 1");

let but2 = Button::default()
    .with_pos(10, 10)
    .with_size(80, 40)
    .with_label("Button 2");

An example of a counter showing use of the builder pattern:

fn main() {
    let app = App::default();
    let mut wind = Window::default()
        .with_size(160, 200)
    let mut frame = Frame::default()
        .with_size(100, 40)
    let mut but_inc = Button::default()
        .above_of(&frame, 0)
    let mut but_dec = Button::default()
        .below_of(&frame, 0)
    /* Event handling */


Event handling must be done after the drawing is done and the main window shown. And must be done in the main thread

Events can be handled using the set_callback method (as above) or the available fltk::app::set_callback() free function, which will handle the default trigger of each widget(like clicks for buttons):

    /* previous hello world code */
    but.set_callback(Box::new(move || frame.set_label("Hello World!")));

Another way is to use message passing:

    /* previous counter code */
    let (s, r) = app::channel::<Message>();

    but_inc.emit(s, Message::Increment);
    but_dec.emit(s, Message::Decrement);
    while app.wait().unwrap() {
        let label: i32 = frame.label().parse().unwrap();
        match r.recv() {
            Some(Message::Increment) => frame.set_label(&(label + 1).to_string()),
            Some(Message::Decrement) => frame.set_label(&(label - 1).to_string()),
            None => (),

For the remainder of the code, check the full example here: https://github.com/MoAlyousef/fltk-rs/blob/master/examples/counter2.rs

For custom event handling, the handle() method can be used:

    some_widget.handle(Box::new(move |ev: Event| {
        match ev {
            /* handle ev */

Handled or ignored events using the handle method should return true, unhandled events should return false. More examples are available in the examples directory.


FLTK offers 4 application themes (called schemes):

  • Base
  • Gtk
  • Gleam
  • Plastic

These can be set using the App::with_scheme() method.

let app = App::default().with_scheme(AppScheme::Gleam);

Themes of individual widgets can be optionally modified using the provided methods in the WidgetExt trait, such as set_color(), set_label_font(), set_frame() etc:

    some_button.set_color(Color::Light1); // You can use one of the provided colors in the fltk enums
    some_button.set_color(Color::from_rgb(255, 0, 0)); // Or you can specify a color by rgb or hex/u32 value


The following are the features offered by the crate:

  • fltk-shared: Builds a shared lib of fltk
  • use-ninja: If you have ninja build installed, it builds faster than make or VS
  • system-fltk: If you would like to use the installed fltk library, should be FLTK 1.4
  • system-libpng: Uses the system libpng
  • system-libjpeg: Uses the system libjpeg
  • system-zlib: Uses the system zlib
  • legacy-opengl: Support of Lagacy OpenGL, the crate uses GLVND by default
  • fltk-bundled: Support for bundled versions of cfltk and fltk on selected platforms
  • no-opengl: Support for systems without OpenGL.


Rust version > 1.38. CMake and a C++11 compiler need to be installed and in your PATH for a crossplatform build from source. This crate also offers a bundled form of fltk on selected platforms, this can be enabled using the fltk-bundled feature flag.

  • Windows: No dependencies.
  • MacOS: No dependencies.
  • Linux: X11 and OpenGL development headers need to be installed for development.

For Debian-based GUI distributions, that means running:

$ sudo apt-get install libx11-dev libxext-dev libxft-dev libxinerama-dev libxcursor-dev libxrender-dev libxfixes-dev libgl1-mesa-dev libglu1-mesa-dev

For RHEL-based GUI distributions, that means running:

$ sudo yum groupinstall "X Software Development" 

For Arch-based GUI distributions, that means running:

$ sudo pacman -S libx11 libxext libxft libxinerama libxcursor libxrender libxfixes libgl mesa --needed

If you have ninja-build installed, you can enable it using the "use-ninja" feature. This should accelerate build times significantly.


please check the FAQ page for frequently asked questions, encountered issues, guides on deployment, and contribution.


To build, just run:

$ git clone https://github.com/MoAlyousef/fltk-rs
$ cd fltk-rs
$ cargo build


To run the examples:

$ cargo run --example editor
$ cargo run --example calculator
$ cargo run --example gallery
$ cargo run --example terminal_colored
$ cargo run --example counter
$ cargo run --example hello
$ cargo run --example hello_button
$ cargo run --example paint
$ cargo run --example glwindow



Setting the scheme to Gtk.



Check the full code for the custom theming.


Setting the scheme to Gtk





Currently implemented widgets

The most commonly widgets are implemented:

  • Image widgets
    • SharedImage
    • BmpImage
    • JpegImage
    • GifImage
    • PngImage
    • SvgImage
    • RgbImage
  • Buttons
    • Button
    • RadioButton
    • ToggleButton
    • RoundButton
    • CheckButton
    • LightButton
    • RepeatButton
    • RadioLightButton
    • RadioRoundButton
  • Dialogs
    • Native FileDialog
    • HelpDialog
    • Message dialog
    • Alert dialog
    • Password dialog
    • Choice dialog
    • Input dialog
  • Frame (Fl_Box)
  • Windows
    • Window
    • DoubleWindow
    • MenuWindow
    • GlWindow
  • Groups
    • Group
    • Pack
    • Tabs
    • Scroll
    • Tile
    • Wizard
    • ColorChooser
  • Text display widgets
    • TextDisplay
    • TextEditor
    • SimpleTerminal
  • Input widgets
    • Input
    • IntInput
    • FloatInput
    • MultilineInput
    • SecretInput
    • FileInput
  • Output widgets
    • Output
    • MultilineOutput
  • Menu widgets
    • MenuBar
    • MenuItem
    • Choice (dropdown list)
  • Valuator widgets
    • Slider
    • NiceSlider
    • ValueSlider
    • Dial
    • LineDial
    • Counter
    • Scrollbar
    • Roller
    • Adjuster
    • ValueInput
    • ValueOutput
    • FillSlider
    • FillDial
    • HorSlider (Horizontal slider)
    • HorFillSlider
    • HorNiceSlider
    • HorValueSlider
  • Browsing widgets
    • Browser
    • SelectBrowser
    • HoldBrowser
    • MultiBrowser
    • FileBrowser
  • Miscelaneous widgets
    • Spinner
    • Clock
    • Chart (several chart types are available)
    • Progress (progress bar)
    • Tooltip
  • Table widgets
    • Table
    • TableRow
  • Trees
    • Tree
    • TreeItem
  • Drawing primitives



~20K SLoC