Eine sehr einfach GUI in Rust
Warum?
Ein große schwäche von Rust (zumindest zum Zeitpunkt des Posts) ist die Abwesenheit eines ordentlichen UI Frameworks. Das einzige das dem ganzen zumindest ansatzweise nachkommt ist iui welches auf libui basiert.
Das Problem ist sehr einfach - schnell fühlt man sich auf den Stand von 1998 zurückversetzt, als man mit MFC-Klassen versucht hat, irgendwie eine UI auf den Bildschirm zu zaubern.
Schnell ist man wieder auf einem UI-Thread der alles für die Anzeige notwendige macht - und den man tunlichst nicht aufhalten soll.
Aber
Für einfache Fenster die ein paar Steuerelemente anzeigen sollen funktioniert es ganz gut.Ausserdem hat libui einen sehr großen Vorteil: Es funktioniert den 3 Desktop-Plattformen gleich.
- Windows
- Linux
- MacOS (incl den M1 - Geräten)
Vorbedingungen:
Neben Rust muss jetzt auch ein compiler vorhanden sein, der libui und ui-sys kompilieren kann. Dazu muss man auf seinem System (falls nicht vorhanden)
- clang
- llvm
- cmake
nachinstallieren.
Nutzt man ein Buildsystem (z.B. das von GitLab oder GitHub), so muss man für linux ausserdem noch libgtk-3-dev via apt dem buildscript hinzufügen.
Nun etwas Code
Als Belohnung kann man dann mittels
use iui::prelude::*;
use iui::controls::*;
use std::sync::Arc;
use std::sync::Mutex;
fn main() {
let ok_arc = Arc::new(Mutex::new(false));
let ui = UI::init().expect("UI Init failed...");
let mut win = Window::new(&ui, "My Window Title", 320, 200, WindowType::NoMenubar);
let mut vbox = VerticalBox::new(&ui);
vbox.set_padded(&ui, true);
// controlls hier hinzufügen
// ok - cancel beispiel
let mut ok_cancel = HorizontalBox::new(&ui);
ok_cancel.set_padded(&ui, true);
let mut cancel_button = Button::new(&ui, "Cancel");
cancel_button.on_clicked(&ui, {
let ok_arc = ok_arc.clone();
let ui = ui.clone();
move |_| {
let mut ok = ok_arc.lock().unwrap();
*ok = false;
ui.quit();
}
});
ok_cancel.append(&ui, cancel_button, LayoutStrategy::Stretchy);
let mut ok_button = Button::new(&ui, "OK");
ok_button.on_clicked(&ui, {
let ok_arc = ok_arc.clone();
let ui = ui.clone();
move |_| {
let mut ok = ok_arc.lock().unwrap();
*ok = true;
ui.quit();
}
});
// am Schluss noch die vertikale Anordnung der Elemente
vbox.append(&ui, ok_cancel, LayoutStrategy::Compact);
win.set_child(&ui, vbox);
win.show(&ui);
ui.main();
let ok = *ok_arc.lock().unwrap();
}
Zusammenfassung
Eine UI-Anwendung in Rust zu bauen ist durchaus möglich - wenn auch momentan nicht ganz so Fancy wie in manch anderen Programmierumgebungen.