Zarządzanie stanem aplikacji
Przechowa Pan/Pani i zaktualizuje dane interfejsu.
Zarządzanie stanem aplikacji to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Learn Rust Coding, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.
Stan w strukturze App
W egui stan aplikacji to zwykłe dane w Rust, przechowywane w strukturze implementującej eframe::App. Nie ma osobnego magazynu ani modelu zarządzanego przez framework.
Pola przechowują wszystko: dane formularzy, wybory, wczytane dane i flagi. W każdej klatce update bezpośrednio odczytuje te pola i modyfikuje je przez &mut self.
struct App {
query: String,
results: Vec<Item>,
selected: Option<usize>,
loading: bool,
}Wyprowadzanie Default
eframe tworzy aplikację w domknięciu przekazanym do run_native. Najprostszy wzorzec to #[derive(Default)] i utworzenie obiektu za pomocą App::default().
W przypadku wartości początkowych, których nie można wyznaczyć domyślnie, należy ręcznie zaimplementować Default albo dodać konstruktor przyjmujący CreationContext, aby skonfigurować na przykład czcionki lub trwałość danych.
impl App {
fn new(cc: &eframe::CreationContext) -> Self {
let mut app = Self::default();
app.dark = cc.egui_ctx.style().visuals.dark_mode;
app
}
}Jedno źródło prawdy
Ponieważ widgety pożyczają &mut do powiązanych z nimi pól, struktura zawsze jest jedynym źródłem prawdy. Nie ma osobnego stanu widoku, który trzeba synchronizować.
Pole wyboru powiązane z &mut self.enabled bezpośrednio odczytuje i aktualizuje tę wartość logiczną — odczytanie jej w dowolnym innym miejscu tej samej klatki zwróci aktualną wartość.
ui.checkbox(&mut self.enabled, "Enabled");
if self.enabled {
ui.label("Feature is on");
}Odroczone modyfikacje
Istnieje subtelny problem z pożyczaniem: często iteruje się po Vec, chcąc jednocześnie usunąć z niego element. Nie można modyfikować wektora, gdy aktywna jest pożyczka współdzielona.
Rozwiązaniem jest zapisanie zamierzonej operacji w zmiennej lokalnej podczas pętli, a następnie wykonanie jej po zakończeniu pętli.
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); }Ekrany sterowane enumem
W aplikacjach wieloekranowych bieżący widok można reprezentować jako pole typu enum. Metoda update dopasowuje do jego wartości, aby zdecydować, co narysować.
Dzięki temu nawigacja jest jawna i wyczerpująca — kompilator wymusza obsługę każdego ekranu, eliminując całe klasy błędów routingu.
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),
}Pamięć egui dla stanu interfejsu
Część stanu dotyczy wyłącznie interfejsu, a nie domeny aplikacji — na przykład zwinięte sekcje, pozycje przewijania i stan przeciągania. egui przechowuje go w ctx.memory, używając identyfikatora widgetu Id jako klucza.
Zwykle nie trzeba uzyskiwać do niego bezpośredniego dostępu, ale ctx.data_mut pozwala przechowywać niewielkie wartości przypisane do identyfikatora, zachowywane między klatkami bez zaśmiecania struktury aplikacji.
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));Praca w tle z kanałami
Nigdy nie blokuj update powolnymi operacjami wejścia-wyjścia — zamrozi to pętlę działającą z częstotliwością 60 klatek na sekundę. Uruchom wątek i komunikuj się za pomocą kanału std::sync::mpsc.
Wątek roboczy odsyła wyniki, a update w każdej klatce opróżnia odbiornik bez blokowania za pomocą try_recv. Wywołaj ctx.request_repaint() z wątku roboczego, aby interfejs został wybudzony po nadejściu danych.
if let Ok(msg) = self.rx.try_recv() {
self.results = msg;
self.loading = false;
}Uruchamianie wątku roboczego
Skopiuj Context oraz nadajnik do wątku. Kopia jest tania — wewnętrznie używa Arc — i pozwala wątkowi żądać odświeżenia.
Przenieś własność danych wejściowych pracy do domknięcia, aby spełnić wymagania borrow checkera i uniknąć problemów z czasem życia.
let tx = self.tx.clone();
let ctx = ctx.clone();
std::thread::spawn(move || {
let data = expensive_load();
let _ = tx.send(data);
ctx.request_repaint();
});Trwałe przechowywanie stanu
eframe może serializować aplikację między kolejnymi uruchomieniami. Włącz funkcję persistence, wyprowadź implementacje serde::Serialize / Deserialize i zaimplementuj App::save.
Podczas uruchamiania odczytaj zapisany stan z cc.storage w konstruktorze, a gdy niczego nie zapisano, użyj wartości domyślnych.
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; }
}Utrzymywanie lekkiej metody update
Ponieważ update uruchamia się w każdej klatce, nie należy wykonywać w nim ponownie kosztownych obliczeń danych pochodnych. Wyniki należy buforować w polach i przeliczać tylko wtedy, gdy zmienią się dane wejściowe.
Typowy wzorzec polega na śledzeniu flagi dirty ustawianej przez Response::changed() i odbudowywaniu buforów na początku update tylko wtedy, gdy flaga jest ustawiona.
if self.dirty {
self.filtered = self.filter_items();
self.dirty = false;
}
for item in &self.filtered { ui.label(&item.name); }Własność zapewnia spójność
Powracający motyw jest następujący: egui opiera zarządzanie stanem na własności Rusta, a nie na frameworku. Struktura jest właścicielem danych, &mut self zapewnia wyłączny dostęp w każdej klatce, a wątki komunikują się za pośrednictwem kanałów.
Nie ma ukrytych subskrypcji ani grafów callbacków, dlatego rozumienie tego, kiedy i jak zmienia się stan, pozostaje lokalne i jawne.
Szybki test
Jak należy wykonać powolne pobieranie danych z sieci?
Podsumowanie
Stan aplikacji to zwykłe pola struktury eframe::App, modyfikowane w każdej klatce przez &mut self, dzięki czemu struktura jest jedynym źródłem prawdy.
Odłóż modyfikacje wykonywane podczas iteracji, modeluj ekrany za pomocą enumów, przenoś powolne operacje do wątków komunikujących się przez kanały i zapisuj stan w magazynie eframe. Utrzymuj update w lekkiej postaci, buforując dane pochodne za flagami zmiany. Następnie zajmiemy się pakowaniem aplikacji do dystrybucji.
Ucz się Rust dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 39
- Lekcje
- 144
Często zadawane pytania
Czy lekcja „Zarządzanie stanem aplikacji” jest bezpłatna?
Tak — pełny tekst „Zarządzanie stanem aplikacji” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Learn Rust Coding, przejdź na CoddyKit PRO. Kurs Learn Rust Coding zawiera 4 lekcji w sumie.
Co nauczysz się w „Zarządzanie stanem aplikacji”?
Przechowa Pan/Pani i zaktualizuje dane interfejsu. Ćwiczysz Learn Rust Coding z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Learn Rust Coding?
Nie wymagamy żadnego doświadczenia. Learn Rust Coding w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Zarządzanie stanem aplikacji”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Learn Rust Coding?
Tak. Każda lekcja Learn Rust Coding zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Podstawy UI w trybie immediate mode
- Widgety i układ
- Zarządzanie stanem aplikacji
- Pakowanie aplikacji desktopowej