0Pricing
Learn Rust Coding · Lekcja

Podstawy UI w trybie immediate mode

Zrozumie Pan/Pani, jak egui renderuje interfejs.

Podstawy UI w trybie immediate mode to bezpłatna lekcja Learn Rust Coding na CoddyKit. To lekcja 1 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.

Znaczenie trybu natychmiastowego

egui to biblioteka GUI działająca w trybie natychmiastowym. W przeciwieństwie do narzędzi działających w trybie zachowywanym (GTK, Qt), w których tworzysz trwałe drzewo widżetów, egui odtwarza cały interfejs od podstaw w każdej klatce.

W każdej klatce kod jest wykonywany od góry do dołu, a widżety są emitowane jako wywołania funkcji. Nie istnieje przechowywany graf węzłów — interfejs jest jedynie efektem ubocznym wykonania closure.

Pętla aktualizacji

Aplikacja egui implementuje eframe::App, którego metoda update jest wywoływana raz na klatkę, zwykle 60 razy na sekundę.

Wewnątrz update opisujesz, jak interfejs powinien wyglądać w tej chwili, na podstawie bieżącego stanu. egui niczego nie porównuje — po prostu ponownie emituje wszystkie elementy.

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &egui::Context, _f: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.label("Hello, egui!");
        });
    }
}

Context i Ui

Wszędzie pojawiają się dwa podstawowe typy. egui::Context to współdzielony, tani do klonowania uchwyt do całego stanu interfejsu w danej klatce.

Ui to obszar, do którego dodajesz widżety. Panele i okna przekazują do closure obiekt &mut Ui; wywołujesz na nim metody takie jak ui.label lub ui.button.

egui::CentralPanel::default().show(ctx, |ui| {
    ui.heading("Dashboard");
    ui.separator();
    ui.label("Widgets go here.");
});

Widżety zwracają odpowiedzi

Ponieważ interfejs jest odtwarzany w każdej klatce, nie można rejestrować wywołań zwrotnych tak jak w narzędziach działających w trybie zachowywanym. Zamiast tego każde wywołanie widżetu natychmiast zwraca obiekt Response.

Sprawdzasz obiekt Response w tej samej klatce: .clicked(), .hovered(), .changed(). Dzięki temu obsługa zdarzeń pozostaje częścią układu interfejsu.

if ui.button("Save").clicked() {
    self.save();
}
let resp = ui.text_edit_singleline(&mut self.name);
if resp.changed() {
    self.dirty = true;
}

Stan jest przechowywany w aplikacji

egui przechowuje niemal żadnych danych aplikacji. Wartości widgetów znajdują się w self w strukturze App, a do widgetów przekazuje się mutowalne referencje.

Pole tekstowe przyjmuje &mut String, a pole wyboru — &mut bool. egui zapisuje zmiany przez referencję, dzięki czemu struktura jest jedynym źródłem prawdy.

struct MyApp {
    name: String,
    enabled: bool,
}

// inside update:
ui.text_edit_singleline(&mut self.name);
ui.checkbox(&mut self.enabled, "Enabled");

Konfiguracja eframe

eframe to oficjalny framework, który udostępnia egui na komputerach stacjonarnych i w przeglądarce. Zarządza natywnym oknem, powierzchnią GPU oraz pętlą zdarzeń.

Aplikację uruchamia się za pomocą eframe::run_native, przekazując tytuł okna, opcje natywne oraz domknięcie tworzące obiekt App.

fn main() -> eframe::Result<()> {
    let opts = eframe::NativeOptions::default();
    eframe::run_native(
        "My App",
        opts,
        Box::new(|_cc| Ok(Box::new(MyApp::default()))),
    )
}

Odświeżanie wywoływane przez dane wejściowe

Domyślnie egui odświeża interfejs tylko wtedy, gdy coś się wydarzy: nastąpi ruch myszy, naciśnięcie klawisza lub jawne żądanie odświeżenia. Dzięki temu aplikacje bezczynne zużywają mniej procesora.

W przypadku animacji lub danych na żywo wywołaj ctx.request_repaint(), aby zaplanować kolejną klatkę, albo użyj request_repaint_after z określonym czasem trwania, aby wykonywać aktualizacje w określonych odstępach.

ui.label(format!("Tick: {}", self.counter));
self.counter += 1;
ctx.request_repaint(); // keep animating

Przeważnie bez trwałych identyfikatorów widgetów

egui wyprowadza tożsamość widgetu z kolejności wywołań i jego położenia, automatycznie generując Id. Ma to znaczenie w przypadku elementów takich jak zwijane nagłówki, które wymagają zachowania pamięci między klatkami.

Gdy dwa widgety mogłyby mieć ten sam identyfikator — na przykład przyciski z taką samą etykietą w pętli — opakuj je w ui.push_id(i, |ui| ...), aby je rozróżnić.

for (i, item) in self.items.iter().enumerate() {
    ui.push_id(i, |ui| {
        if ui.button(&item.label).clicked() {
            println!("clicked {}", i);
        }
    });
}

Kompromisy trybu natychmiastowego

Tryb natychmiastowy sprawia, że kod interfejsu jest wprost sterowany danymi: instrukcja if pokazuje lub ukrywa sekcję, a pętla for renderuje listę. Nie trzeba ręcznie dodawać ani usuwać węzłów, a model i widok nie mogą się rozsynchronizować.

Ceną jest ponowne wykonywanie całego interfejsu w każdej klatce, dlatego praca wykonywana w każdej klatce powinna być lekka i nie należy umieszczać kosztownych obliczeń wewnątrz update.

if self.logged_in {
    ui.label(format!("Welcome, {}", self.user));
} else {
    ui.label("Please sign in.");
}

Minimalna kompletna aplikacja

Łącząc wszystko: struktura przechowuje stan, update go rysuje, a main uruchamia okno. To cały szkielet dowolnego desktopowego programu egui.

Cała reszta — układ, motywy i pakowanie — opiera się na tej pętli.

#[derive(Default)]
struct App { count: i32 }

impl eframe::App for App {
    fn update(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            if ui.button("+1").clicked() { self.count += 1; }
            ui.label(format!("Count: {}", self.count));
        });
    }
}

Dlaczego Rust świetnie współpracuje z egui

Projekt egui wykorzystuje mocne strony Rusta. Pożyczenie &mut self w ramach pojedynczego wywołania update sprawia, że borrow checker gwarantuje brak wyścigów danych między widgetami a modelem.

Nie ma tu callbacków przechwytujących współdzielony mutowalny stan ani grafów Rc<RefCell> wymuszanych przez trwałe drzewo — jest zwykła własność i jedno mutowalne przejście w każdej klatce.

Szybki test

Sprawdź, czy rozumie Pan/Pani tryb natychmiastowy.

Podsumowanie

egui działa w trybie natychmiastowym: cały interfejs jest tworzony od nowa w każdej klatce wewnątrz eframe::App::update. Widgety są wywołaniami funkcji zwracającymi obiekt Response, który można od razu sprawdzić.

Dane znajdują się w self i są przekazywane przez mutowalną referencję, dzięki czemu borrow checker utrzymuje synchronizację modelu i widoku. eframe::run_native obsługuje okno i pętlę zdarzeń. Następnie przyjrzymy się zestawowi widgetów i systemowi układu.

Często zadawane pytania

Czy lekcja „Podstawy UI w trybie immediate mode” jest bezpłatna?

Tak — pełny tekst „Podstawy UI w trybie immediate mode” 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 „Podstawy UI w trybie immediate mode”?

Zrozumie Pan/Pani, jak egui renderuje interfejs. Ć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 1 z 4.

Ile czasu zajmuje lekcja „Podstawy UI w trybie immediate mode”?

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

  1. Podstawy UI w trybie immediate mode
  2. Widgety i układ
  3. Zarządzanie stanem aplikacji
  4. Pakowanie aplikacji desktopowej
← Powrót do Learn Rust Coding