Fondamenti dell'interfaccia UI immediate-mode
Comprenda come esegui il rendering egui.
Fondamenti dell'interfaccia UI immediate-mode è una lezione Learn Rust Coding gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Learn Rust Coding, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Learn Rust Coding include 4 lezioni in totale.
Cosa significa immediate mode
egui è una libreria GUI in modalità immediate-mode. A differenza dei toolkit in modalità retained (GTK, Qt), in cui si costruisce un albero persistente di widget, egui ricostruisce l'intera interfaccia da zero a ogni frame.
Il codice viene eseguito dall'alto verso il basso a ogni frame e genera i widget come chiamate di funzione. Non esiste un grafo di nodi memorizzato: l'interfaccia è semplicemente un effetto collaterale dell'esecuzione della closure.
Il ciclo di aggiornamento
Un'app egui implementa eframe::App, il cui metodo update viene chiamato una volta per frame, in genere 60 volte al secondo.
All'interno di update descrive l'aspetto che l'interfaccia deve avere in questo momento, dato lo stato corrente. egui non calcola differenze: emette semplicemente tutto nuovamente.
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 e Ui
Due tipi fondamentali compaiono ovunque. egui::Context è l'handle condiviso, economico da clonare, per l'intero stato dell'interfaccia nel frame.
Ui è una regione in cui aggiungere i widget. I pannelli e le finestre forniscono un &mut Ui all'interno della closure; su di esso si chiamano metodi come ui.label o ui.button.
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Dashboard");
ui.separator();
ui.label("Widgets go here.");
});I widget restituiscono Response
Poiché l'interfaccia viene ricostruita a ogni frame, non è possibile registrare callback come nei toolkit retained. Al contrario, ogni chiamata a un widget restituisce immediatamente una Response.
Esamini la Response nello stesso frame: .clicked(), .hovered(), .changed(). In questo modo la gestione degli eventi rimane integrata nel layout.
if ui.button("Save").clicked() {
self.save();
}
let resp = ui.text_edit_singleline(&mut self.name);
if resp.changed() {
self.dirty = true;
}Lo stato è a Suo carico
egui memorizza pochissimi dati dell'applicazione. I valori dei widget risiedono in self nella struct App, e Lei passa riferimenti mutabili ai widget.
Un campo di testo riceve &mut String; una casella di controllo riceve &mut bool. egui scrive nuovamente attraverso il riferimento, quindi la Sua struct è l'unica fonte di verità.
struct MyApp {
name: String,
enabled: bool,
}
// inside update:
ui.text_edit_singleline(&mut self.name);
ui.checkbox(&mut self.enabled, "Enabled");Configurazione di eframe
eframe è il framework ufficiale che ospita egui su desktop e web. Gestisce la finestra nativa, la superficie GPU e il ciclo degli eventi.
Avvii l'applicazione con eframe::run_native, passando il titolo della finestra, le opzioni native e una closure che costruisce la Sua App.
fn main() -> eframe::Result<()> {
let opts = eframe::NativeOptions::default();
eframe::run_native(
"My App",
opts,
Box::new(|_cc| Ok(Box::new(MyApp::default()))),
)
}Ridisegno guidato dall'input
Per impostazione predefinita, egui ridisegna l'interfaccia solo quando accade qualcosa: movimento del mouse, pressione di un tasto o richiesta esplicita. Questo riduce il consumo della CPU nelle app inattive.
Per animazioni o dati aggiornati in tempo reale, chiami ctx.request_repaint() per pianificare un altro frame, oppure request_repaint_after con una durata per aggiornamenti programmati.
ui.label(format!("Tick: {}", self.counter));
self.counter += 1;
ctx.request_repaint(); // keep animatingNessun ID persistente dei widget (per lo più)
egui ricava l'identità del widget dall'ordine e dalla posizione delle chiamate, generando automaticamente un Id. Questo è importante per elementi come le intestazioni comprimibili, che richiedono una memoria stabile tra i frame.
Quando due widget potrebbero entrare in conflitto, ad esempio pulsanti con la stessa etichetta in un ciclo, li racchiuda in ui.push_id(i, |ui| ...) per distinguerli.
for (i, item) in self.items.iter().enumerate() {
ui.push_id(i, |ui| {
if ui.button(&item.label).clicked() {
println!("clicked {}", i);
}
});
}Compromessi della modalità immediate
La modalità immediate rende il codice dell'interfaccia immediatamente guidato dai dati: un if mostra o nasconde una sezione, un for visualizza un elenco. Non è necessario aggiungere o rimuovere manualmente i nodi e non si verificano desincronizzazioni tra modello e vista.
Il costo è che l'intera interfaccia viene rieseguita a ogni frame; mantenga quindi contenuto il lavoro per frame ed eviti calcoli pesanti all'interno di update.
if self.logged_in {
ui.label(format!("Welcome, {}", self.user));
} else {
ui.label("Please sign in.");
}App completa minimale
Riunendo tutti gli elementi: una struct contiene lo stato, update lo disegna e main esegue la finestra. Questo è lo scheletro completo di qualsiasi programma egui desktop.
Tutto il resto, dal layout alla tematizzazione fino alla distribuzione, si basa su questo ciclo.
#[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));
});
}
}Perché Rust apprezza egui
Il design di egui valorizza i punti di forza di Rust. Il prestito di &mut self in una singola chiamata a update consente al borrow checker di garantire l'assenza di data race tra i widget e il modello.
Non ci sono callback che catturano stato mutabile condiviso né grafi Rc<RefCell> imposti da un albero retained: solo la normale ownership e un unico passaggio mutabile per frame.
Verifica rapida
Verifichi la Sua comprensione della modalità immediate.
Riepilogo
egui funziona in modalità immediate-mode: l’intera UI viene ricostruita a ogni frame all’interno di eframe::App::update. I widget sono chiamate di funzione che restituiscono una Response da esaminare subito.
I dati risiedono in self e vengono passati tramite un riferimento mutabile, quindi il borrow checker mantiene sincronizzati modello e vista. eframe::run_native gestisce la finestra e il ciclo degli eventi. Ora esploreremo la raccolta di widget e il sistema di layout.
Domande Frequenti
La lezione «Fondamenti dell'interfaccia UI immediate-mode» è gratuita?
Sì — il testo completo di «Fondamenti dell'interfaccia UI immediate-mode» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Learn Rust Coding, passa a CoddyKit PRO. Il corso Learn Rust Coding include 4 lezioni in totale.
Cosa imparerò in «Fondamenti dell'interfaccia UI immediate-mode»?
Comprenda come esegui il rendering egui. Eserciti Learn Rust Coding con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Learn Rust Coding?
Non è richiesta alcuna esperienza precedente. Learn Rust Coding su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Fondamenti dell'interfaccia UI immediate-mode»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Learn Rust Coding?
Sì. Ogni lezione Learn Rust Coding include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Fondamenti dell'interfaccia UI immediate-mode
- Widget e layout
- Gestire lo stato dell'app
- Distribuire un'app desktop