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(); | |
| } |