Easy to use

Relm provides a very intuitive declarative syntax to create GUI applications and shows good error messages similar to the ones emitted by the compiler itself.

More ›

Efficient

Relm generates the same gtk-rs code you would write by hand.

More ›

Easy to learn

There are extensive resources and examples (not yet) to learn how to use relm.

More ›

Start using Relm now ›

Sample Code

use gtk::{ButtonExt, Inhibit, LabelExt, OrientableExt, WidgetExt};
use gtk::Orientation::Vertical;
use relm::Widget;
use relm_derive::{Msg, widget};

#[widget]
impl Widget for Win {
    view! {
        gtk::Window {
            gtk::Box {
                orientation: Vertical,
                #[name="inc_button"]
                gtk::Button {
                    clicked => Increment,
                    label: "+",
                },
                #[name="label"]
                gtk::Label {
                    text: &self.model.counter.to_string(),
                },
                #[name="dec_button"]
                gtk::Button {
                    clicked => Decrement,
                    label: "-",
                },
            },
            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }

    fn update(&mut self, event: Msg) {
        match event {
            Decrement => self.model.counter -= 1,
            Increment => self.model.counter += 1,
            Quit => gtk::main_quit(),
        }
    }

    fn model() -> Model {
        Model {
            counter: 0,
        }
    }
}

fn main() {
    Win::run(()).expect("Win::run failed");
}

use self::Msg::*;

pub struct Model {
    counter: i32,
}

#[derive(Msg)]
pub enum Msg {
    Decrement,
    Increment,
    Quit,
}
use gtk::{EditableSignals, EntryExt, Inhibit, LabelExt, OrientableExt, WidgetExt};
use gtk::Orientation::Vertical;
use relm::Widget;
use relm_derive::{Msg, widget};

#[widget]
impl Widget for Win {
    view! {
        gtk::Window {
            gtk::Box {
                orientation: Vertical,
                #[name="entry"]
                gtk::Entry {
                    changed(entry) => {
                        let text = entry.get_text().to_string();
                        let len = text.len();
                        Change(text, len)
                    },
                    placeholder_text: Some("Text to reverse"),
                },
                #[name="label"]
                gtk::Label {
                    text: &self.model.content,
                },
            },
            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }

    fn update(&mut self, event: Msg) {
        match event {
            Change(text, len) => {
                self.model.content = text.chars().rev().collect();
                self.model.content += &format!(" ({})", len);
            },
            Quit => gtk::main_quit(),
        }
    }

    fn model() -> Model {
        Model {
            content: String::new(),
        }
    }
}

fn main() {
    Win::run(()).expect("Win::run failed");
}

use self::Msg::*;

pub struct Model {
    content: String,
}

#[derive(Msg)]
pub enum Msg {
    Change(String, usize),
    Quit,
}
use gtk::{Inhibit, WidgetExt};
use relm_derive::{Msg, widget};
use relm::Widget;
use webkit2gtk::WebViewExt;

#[widget]
impl Widget for Win {
    view! {
        gtk::Window {
            #[name="webview"]
            webkit2gtk::WebView {
            },
            delete_event(_, _) => (Quit, Inhibit(false)),
        }
    }

    fn init_view(&mut self) {
        self.widgets.webview.load_uri("https://crates.io/");
    }

    fn update(&mut self, event: Msg) {
        match event {
            Quit => gtk::main_quit(),
        }
    }

    fn model() -> Model {
        Model {
        }
    }
}

use self::Msg::*;

pub struct Model {
}

#[derive(Msg)]
pub enum Msg {
    Quit,
}

fn main() {
    Win::run(()).expect("Win::run failed");
}
use gtk::{ButtonExt, GridExt, Inhibit, WidgetExt};
use relm::Widget;
use relm_derive::{Msg, widget};

#[widget]
impl Widget for Win {
    view! {
        gtk::Window {
            gtk::Grid {
                gtk::Button {
                    label: "7",
                    cell: {
                        left_attach: 0,
                        top_attach: 0,
                    },
                },
                gtk::Button {
                    label: "8",
                    cell: {
                        left_attach: 1,
                        top_attach: 0,
                    },
                },
                gtk::Button {
                    label: "9",
                    cell: {
                        left_attach: 2,
                        top_attach: 0,
                    },
                },
                gtk::Button {
                    label: "4",
                    cell: {
                        left_attach: 0,
                        top_attach: 1,
                    },
                },
                gtk::Button {
                    label: "5",
                    cell: {
                        left_attach: 1,
                        top_attach: 1,
                    },
                },
                gtk::Button {
                    label: "6",
                    cell: {
                        left_attach: 2,
                        top_attach: 1,
                    },
                },
                gtk::Button {
                    label: "1",
                    cell: {
                        left_attach: 0,
                        top_attach: 2,
                    },
                },
                gtk::Button {
                    label: "2",
                    cell: {
                        left_attach: 1,
                        top_attach: 2,
                    },
                },
                gtk::Button {
                    label: "3",
                    cell: {
                        left_attach: 2,
                        top_attach: 2,
                    },
                },
                gtk::Button {
                    label: "+/-",
                    cell: {
                        left_attach: 0,
                        top_attach: 3,
                    },
                },
                gtk::Button {
                    label: "0",
                    cell: {
                        left_attach: 1,
                        top_attach: 3,
                    },
                },
                gtk::Button {
                    label: ".",
                    cell: {
                        left_attach: 2,
                        top_attach: 3,
                    },
                }
            },
            delete_event(_, _) => (Quit, Inhibit(false))
        }
    }

    fn update(&mut self, event: Msg) {
        match event {
            Quit => gtk::main_quit(),
        }
    }

    fn model() {
    }
}

use self::Msg::*;

#[derive(Msg)]
pub enum Msg {
    Quit,
}

fn main() {
    Win::run(()).expect("Win::run failed");
}
sample

New Blog Articles

A big release for relm

Read More ›

More Articles