Noções Básicas de GUI
8 exemplos para você começar com desenvolvimento de GUI desktop em Rust - 6 básicos e 2 intermediários.
Pré-requisitos
# Caminho do Tauri
npm create tauri-app@latest
# Caminho do egui
cargo add eframe egui
# Caminho do iced
cargo add icedFerramentas: Os exemplos de backend visam Rust 1.97.0 (edição 2024). O Tauri também precisa do Node para a cadeia de ferramentas frontend.
Exemplos Básicos
1. Janela egui mínima
UI de modo imediato em um aplicativo eframe.
fn main() -> eframe::Result<()> {
eframe::run_native(
"Hello egui",
eframe::NativeOptions::default(),
Box::new(|_cc| Ok(Box::new(MyApp::default()))),
)
}
#[derive(Default)]
struct MyApp {}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Hello from Rust GUI");
});
}
}updateé executado a cada frame - mantenha o trabalho leve ou use o perfilador de CPU.- egui gerencia o layout a cada frame - ótimo para ferramentas, menos para cromos nativos complexos.
- A manipulação de janelas multiplataforma é feita por
winitsob o eframe.
Relacionado: egui
2. Botão contador iced
O enum Message no estilo Elm impulsiona as atualizações.
use iced::widget::{button, column, text, Column};
use iced::Element;
#[derive(Debug, Clone)]
enum Message {
Increment,
}
fn view(count: &i32) -> Element<Message> {
column![
text(format!("Count: {count}")),
button("+").on_press(Message::Increment),
]
.into()
}- A função
viewpura mapeia o estado para widgets. updateaplica mensagens imutavelmente - padrão de reducer testável.- Estilização via temas do iced e regras personalizadas semelhantes a CSS.
Relacionado: iced
3. Tauri invoke do frontend
Comando Rust que pode ser chamado da UI JavaScript.
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {name}!")
}- Comandos são a fronteira de IPC - valide todas as entradas em Rust.
- Mantenha trabalhos pesados fora da thread principal com comandos assíncronos quando necessário.
- O frontend pode ser React, Svelte ou vanilla - Rust é responsável pelas APIs sensíveis à segurança.
Relacionado: Tauri
4. Compartilhar estado com Arc<Mutex<_>> no Tauri
Vários comandos modificando o estado compartilhado do aplicativo.
use std::sync::Mutex;
use tauri::State;
struct AppState {
counter: Mutex<i32>,
}
#[tauri::command]
fn increment(state: State<AppState>) -> i32 {
let mut c = state.counter.lock().unwrap();
*c += 1;
*c
}State<T>gerencia o tempo de vida entre invocações.- Prefira
tokio::sync::Mutexem comandos assíncronos para evitar bloquear o runtime assíncrono. - Documente a ordem de bloqueio se houver múltiplos mutexes.
Relacionado: Estado & Arquitetura
5. Abrir um diálogo de arquivo nativo (conceito)
Delegue a seleção do sistema de arquivos para APIs do sistema operacional via plugin ou crate rfd.
fn pick_file() -> Option<std::path::PathBuf> {
rfd::FileDialog::new().pick_file()
}- Execute diálogos na thread da UI de acordo com os requisitos da plataforma.
- Retorne caminhos para o núcleo Rust para análise - não confie cegamente nos caminhos (symlinks).
- Aplicativos Tauri em sandbox precisam de permissões com escopo em
tauri.conf.json.
Relacionado: Integração Nativa
6. Menu da aplicação e bandeja (conceito)
Aplicativos desktop precisam de sair, preferências e comportamento em segundo plano.
- Tauri: APIs
tauri::menue de bandeja no hook de configuração Rust. - egui: crates de terceiros ou barra de menu mínima dentro do aplicativo.
- iced: configurações de janela e integrações específicas da plataforma variam.
Relacionado: Integração Nativa
Exemplos Intermediários
7. egui + configurações persistentes
Carrega a configuração na inicialização, salva em caso de alteração com serde JSON.
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Default)]
struct Settings {
dark_mode: bool,
}- Debounce para salvamentos - não escreva no disco a cada alternância de frame.
- Armazene no diretório de dados do aplicativo da plataforma - veja a página de integração nativa.
- Versiona a struct de configurações para migrações compatíveis com versões futuras.
Relacionado: Estado & Arquitetura
8. Build de release e bundle
Envie .app, .msi ou .deb com ícones e metadados.
cargo tauri build
# ou cargo install cargo-bundle && cargo bundle- Assinatura de código necessária para uma experiência suave com o Gatekeeper do macOS.
- A atualização automática requer um endpoint HTTPS e verificação de assinatura.
- Teste em uma VM limpa sem toolchains de desenvolvimento instaladas.
Relacionado: Empacotamento & Distribuição
Versões da Stack: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.