0Pricing
Learn Rust Coding · Lektion

App-Zustand verwalten

Speichern und aktualisieren Sie UI-Daten.

App-Zustand verwalten ist eine kostenlose Learn Rust Coding-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Learn Rust Coding-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Learn Rust Coding-Kurs umfasst insgesamt 4 Lektionen.

Zustand in der App-Struktur

In egui besteht der Zustand Ihrer Anwendung aus gewöhnlichen Rust-Daten, die in der Struktur liegen, welche eframe::App implementiert. Es gibt keinen speziellen Store und kein vom Framework verwaltetes Modell.

Die Felder enthalten alles: Formulareingaben, Auswahlen, geladene Daten und Flags. In jedem Frame liest und verändert update diese Felder direkt über &mut self.

struct App {
    query: String,
    results: Vec<Item>,
    selected: Option<usize>,
    loading: bool,
}

Default ableiten

eframe erstellt Ihre Anwendung in einer an run_native übergebenen Closure. Das einfachste Muster besteht aus #[derive(Default)] und der Erstellung mit App::default().

Für Anfangswerte, die keine Defaults sind, implementieren Sie Default von Hand oder ergänzen Sie einen Konstruktor, der den CreationContext für die Einrichtung von beispielsweise Schriftarten oder Persistenz entgegennimmt.

impl App {
    fn new(cc: &eframe::CreationContext) -> Self {
        let mut app = Self::default();
        app.dark = cc.egui_ctx.style().visuals.dark_mode;
        app
    }
}

Einzige Quelle der Wahrheit

Da Widgets ihre zugrunde liegenden Felder als &mut ausleihen, ist die Struktur immer die einzige Quelle der Wahrheit. Es gibt keinen separaten Ansichtsstatus, der synchron gehalten werden muss.

Eine an &mut self.enabled gebundene Checkbox spiegelt diesen Bool direkt wider und aktualisiert ihn. Wenn Sie ihn im selben Frame an anderer Stelle lesen, sehen Sie den aktuellen Wert.

ui.checkbox(&mut self.enabled, "Enabled");
if self.enabled {
    ui.label("Feature is on");
}

Änderungen zurückstellen

Ein subtiler Borrow-Konflikt: Häufig durchlaufen Sie einen Vec und möchten ihn dabei verändern. Sie können den Vektor nicht ändern, solange ein gemeinsamer Borrow aktiv ist.

Die Lösung besteht darin, während der Schleife die geplante Aktion in einer lokalen Variable zu speichern und sie nach dem Ende der Schleife anzuwenden.

let mut to_remove = None;
for (i, item) in self.items.iter().enumerate() {
    ui.horizontal(|ui| {
        ui.label(&item.name);
        if ui.button("x").clicked() { to_remove = Some(i); }
    });
}
if let Some(i) = to_remove { self.items.remove(i); }

Durch Enums gesteuerte Bildschirme

Bei Anwendungen mit mehreren Bildschirmen modellieren Sie die aktuelle Ansicht als Enum-Feld. Die Methode update führt darauf ein Match aus, um zu entscheiden, was gezeichnet werden soll.

Dadurch bleibt die Navigation explizit und vollständig: Der Compiler zwingt Sie, jeden Bildschirm zu behandeln, und verhindert so ganze Klassen von Routing-Fehlern.

enum Screen { Home, Settings, About }

match self.screen {
    Screen::Home => self.draw_home(ui),
    Screen::Settings => self.draw_settings(ui),
    Screen::About => self.draw_about(ui),
}

egui-Speicher für den UI-Zustand

Mancher Zustand betrifft ausschließlich die UI und nicht Ihre Domäne – etwa eingeklappte Abschnitte, Scrollpositionen oder der Ziehstatus. egui speichert ihn in ctx.memory, anhand der Widget-Id identifiziert.

Sie greifen nur selten direkt darauf zu, aber mit ctx.data_mut können Sie kleine, an eine ID gebundene Werte ablegen, die zwischen Frames bestehen bleiben, ohne Ihre App-Struktur zu überladen.

let id = egui::Id::new("my_toggle");
let mut open = ctx.data_mut(|d| d.get_temp::<bool>(id).unwrap_or(false));
ui.checkbox(&mut open, "Open");
ctx.data_mut(|d| d.insert_temp(id, open));

Hintergrundarbeit mit Channels

Blockieren Sie update niemals mit langsamer I/O – dadurch friert die 60-FPS-Schleife ein. Starten Sie einen Thread und kommunizieren Sie über einen std::sync::mpsc-Channel.

Der Worker sendet Ergebnisse zurück; update leert den Receiver in jedem Frame nicht blockierend mit try_recv. Rufen Sie im Worker ctx.request_repaint() auf, damit die UI beim Eintreffen von Daten aufgeweckt wird.

if let Ok(msg) = self.rx.try_recv() {
    self.results = msg;
    self.loading = false;
}

Den Worker starten

Klonen Sie den Context und den Sender in den Thread. Der Klon ist kostengünstig – intern handelt es sich um ein Arc – und ermöglicht es dem Worker, Neuzeichnungen anzufordern.

Übertragen Sie das Eigentum an den Arbeitseingaben in die Closure, um die Anforderungen des Borrow Checkers zu erfüllen und Probleme mit Lebensdauern zu vermeiden.

let tx = self.tx.clone();
let ctx = ctx.clone();
std::thread::spawn(move || {
    let data = expensive_load();
    let _ = tx.send(data);
    ctx.request_repaint();
});

Zustand persistieren

eframe kann Ihre Anwendung zwischen Ausführungen serialisieren. Aktivieren Sie das persistence-Feature, leiten Sie serde::Serialize / Deserialize ab und implementieren Sie App::save.

Lesen Sie beim Start den gespeicherten Zustand in Ihrem Konstruktor aus cc.storage und verwenden Sie Defaults, wenn nichts gespeichert wurde.

fn save(&mut self, storage: &mut dyn eframe::Storage) {
    eframe::set_value(storage, eframe::APP_KEY, self);
}
// in new():
if let Some(s) = cc.storage {
    if let Some(app) = eframe::get_value(s, eframe::APP_KEY) { return app; }
}

update kostengünstig halten

Da update in jedem Frame ausgeführt wird, sollten Sie dort keine aufwendigen abgeleiteten Daten neu berechnen. Cachen Sie Ergebnisse in Feldern und berechnen Sie sie nur neu, wenn sich Eingaben ändern.

Ein übliches Muster besteht darin, ein dirty-Flag zu führen, das durch Response::changed() gesetzt wird, und die Caches am Anfang von update nur dann neu aufzubauen, wenn das Flag gesetzt ist.

if self.dirty {
    self.filtered = self.filter_items();
    self.dirty = false;
}
for item in &self.filtered { ui.label(&item.name); }

Ownership sorgt für klare Zuständigkeiten

Das wiederkehrende Thema: egui setzt bei der Zustandsverwaltung auf Rusts Ownership statt auf Frameworks. Ihre Struktur besitzt die Daten, &mut self gewährt pro Frame exklusiven Zugriff, und Threads kommunizieren über Channels.

Es gibt keine verborgenen Subscriptions oder Callback-Strukturen. Daher bleibt nachvollziehbar, wann und wie sich der Zustand ändert – lokal und explizit.

Kurze Überprüfung

Wie sollten Sie einen langsamen Netzwerkabruf ausführen?

Zusammenfassung

Der Anwendungszustand besteht aus gewöhnlichen Feldern der eframe::App-Struktur, die in jedem Frame über &mut self verändert werden. Dadurch ist die Struktur die einzige Quelle der Wahrheit.

Stellen Sie Änderungen während des Durchlaufens zurück, modellieren Sie Bildschirme mit Enums, verlagern Sie langsame Arbeit mithilfe von Channels in Threads und persistieren Sie den Zustand mit dem Speicher von eframe. Halten Sie update kostengünstig, indem Sie abgeleitete Daten hinter Dirty-Flags cachen. Als Nächstes geht es um die Paketierung Ihrer Anwendung für die Verteilung.

Häufig gestellte Fragen

Ist die Lektion „App-Zustand verwalten“ kostenlos?

Ja — der vollständige Text von „App-Zustand verwalten“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Learn Rust Coding-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Learn Rust Coding-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „App-Zustand verwalten“?

Speichern und aktualisieren Sie UI-Daten. Du übst Learn Rust Coding mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Learn Rust Coding zu starten?

Keine Vorkenntnisse erforderlich. Learn Rust Coding auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „App-Zustand verwalten“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Learn Rust Coding-Lektion Code schreiben und ausführen?

Ja. Jede Learn Rust Coding-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Grundlagen der Immediate-Mode-UI
  2. Widgets und Layout
  3. App-Zustand verwalten
  4. Eine Desktop-App paketieren
← Zurück zu Learn Rust Coding