Rust + GTK4 + Relm
This is a simple example of Relm 4 application where:
- the user can enter its name in a text field
- update the greet message with a button
[package] | |
name = "greet-user" | |
version = "0.1.0" | |
edition = "2021" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[dependencies] | |
gtk = {version = "0.3", package = "gtk4"} | |
relm4 = "0.2" | |
relm4-macros = "0.2" | |
relm4-components = "0.2" |
use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt, EntryExt, EditableExt}; | |
use relm4::{send, AppUpdate, Model, RelmApp, Sender, WidgetPlus, Widgets}; | |
#[derive(Default)] | |
struct AppModel { | |
name: String, | |
value: String, | |
} | |
enum AppMsg { | |
Greet, | |
SetName(String), | |
} | |
impl Model for AppModel { | |
type Msg = AppMsg; | |
type Widgets = AppWidgets; | |
type Components = (); | |
} | |
impl AppUpdate for AppModel { | |
fn update(&mut self, msg: AppMsg, _components: &(), _sender: Sender<AppMsg>) -> bool { | |
match msg { | |
AppMsg::Greet => { | |
let substitute = if self.name.len() > 0 {self.name.clone()} else {String::from("")}; | |
self.value = format!("Hello {} !", substitute); | |
}, | |
AppMsg::SetName(new_name) => { | |
self.name = new_name; | |
} | |
} | |
true | |
} | |
} | |
#[relm4_macros::widget] | |
impl Widgets<AppModel, ()> for AppWidgets { | |
view! { | |
gtk::ApplicationWindow { | |
set_title: Some("Greet user"), | |
set_default_width: 300, | |
set_default_height: 200, | |
set_child = Some(>k::Box) { | |
set_orientation: gtk::Orientation::Vertical, | |
set_margin_all: 5, | |
set_spacing: 5, | |
append = >k::Box { | |
set_spacing: 10, | |
set_orientation: gtk::Orientation::Horizontal, | |
append: name_entry = >k::Entry { | |
set_placeholder_text: Some("Your name"), | |
connect_changed(sender) => move |name_entry| { | |
send!(sender, AppMsg::SetName(format!("{}", name_entry.text()))); | |
} | |
}, | |
append = >k::Button { | |
set_label: "Let CPU greet", | |
connect_clicked(sender) => move |_| { | |
send!(sender, AppMsg::Greet); | |
} | |
} | |
}, | |
append = >k::Label { | |
set_margin_all: 5, | |
set_label: watch! { model.value.as_str() }, | |
} | |
}, | |
} | |
} | |
} | |
fn main() { | |
let model = AppModel::default(); | |
let app = RelmApp::new(model); | |
app.run(); | |
} |