Intégration de la barre des tâches système dans une application egui sous Windows

Pour développer des applications de bureau avec egui et eframe sur Windows, l'ajout d'une barre des tâches système est une fonctionnalité couramment requise. Rust propose plusieurs bibliothèques pour gérer cela, chacune avec ses avantages spécifiques.

Les options populaires incluent systray, qui offre une solution légère multiplateforme, et tray_rust, conçue spécifiquement pour Windows en s'appuyant sur WinAPI. D'autres alternatives comme winapi-rs, une bibliothèque de liaisons WinAPI complète, native-windows-gui, pour des interfaces graphiques natives, et trayify, qui fournit des fonctionnalités avancées telles que des icônes et menus personnalisés, sont également disponibles.

Lorsque vous utilisez le framework eframe, il est possible d'intégrer ces bibliothèques. Voici un exemple utilisant systray pour créer une application avec une barre des tâches fonctionnelle et une interface egui.

use eframe::{egui, epi};
use systray::{App, SystrayMsg, MenuAction, MsgReceiver, MsgSender};

struct TrayApp {
    msg_receiver: MsgReceiver,
    tray_app: App,
}

impl epi::App for TrayApp {
    fn name(&self) -> &str {
        "TrayDemo"
    }

    fn update(&mut self, ctx: &egui::CtxRef, frame: &mut epi::Frame<'_>) {
        while let Ok(message) = self.msg_receiver.try_recv() {
            match message {
                SystrayMsg::MenuSelected(_) => {
                    // Gérer la sélection d'un élément de menu
                }
                SystrayMsg::Close => {
                    frame.quit();
                }
                _ => {}
            }
        }

        egui::Window::new("Fenêtre Principale").show(ctx, |ui| {
            ui.label("Contenu de l'application");
        });

        let _ = self.tray_app.update_tooltip("Info-bulle mise à jour");
        let _ = self.tray_app.wait_event(Some(std::time::Duration::from_millis(16)));
    }
}

fn main() {
    let (sender, receiver): (MsgSender, MsgReceiver) = systray::create_channel();
    let tray = App::new("Mon Application", "icon_name").unwrap();

    tray.add_menu_item("Afficher", || println!("Option Afficher")).unwrap();
    tray.add_separator().unwrap();
    tray.add_menu_item("Quitter", move || {
        sender.send(SystrayMsg::Close).unwrap();
    }).unwrap();

    let app = TrayApp {
        msg_receiver: receiver,
        tray_app: tray,
    };

    eframe::run_native(Box::new(app));
}

Cette approche permet de gérer les événements de la barre des tâches tout en maintenant l'interface egui réactive. Une méthode alternative utilise la bibliothèque tray_item, comme illustré ci-dessous, avec une gestion des messages via des canaux.

use std::sync::mpsc;
use tray_item::TrayIcon;

enum TrayAction {
    ShowMsg,
    Exit,
}

fn main() {
    let mut icon = TrayIcon::new("ExempleTray", "icon").unwrap();
    icon.set_label("Statut: Actif").unwrap();

    icon.add_menu_item("Salutation", || println!("Bonjour !")).unwrap();

    let (tx, rx) = mpsc::channel();

    icon.add_menu_item("Fermer", move || {
        tx.send(TrayAction::Exit).unwrap();
    }).unwrap();

    loop {
        match rx.recv() {
            Ok(TrayAction::Exit) => break,
            _ => {}
        }
    }
}

Étiquettes: Rust egui eframe Windows system-tray

Publié le 13 juillet à 22h56