Rust文件对话框库egui-file-dialog的使用:轻量级跨平台GUI文件选择器,支持EGUI集成
egui-file-dialog
功能特性
- 选择文件或目录
- 保存文件(提示用户输入目标路径)
- 询问用户是否覆盖现有文件的对话框
- 同时选择多个文件和文件夹(在Linux/Windows上使用Ctrl/Shift+点击,在macOS上使用Cmd/Shift+点击)
- 以普通窗口或模态窗口打开对话框
- 创建新文件夹
- 键盘导航
- 显示或隐藏隐藏文件和文件夹的选项
- 显示或隐藏系统文件的选项
- 导航按钮打开父目录或之前的目录
- 在目录中搜索项目
- 添加用户可以从下拉菜单中选择的文件过滤器
- 用户目录(Home、Documents等)和系统磁盘的快捷方式
- 将文件夹固定到左侧边栏
- 手动编辑路径
- 虚拟文件系统支持
示例代码
以下是使用egui-file-dialog的基本示例:
use std::path::PathBuf;
use eframe::egui;
use egui_file_dialog::FileDialog;
struct MyApp {
file_dialog: FileDialog,
picked_file: Option<PathBuf>,
}
impl MyApp {
pub fn new(_cc: &eframe::CreationContext) -> Self {
Self {
// 创建一个新的文件对话框对象
file_dialog: FileDialog::new(),
picked_file: None,
}
}
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
if ui.button("Pick file").clicked() {
// 打开文件对话框选择文件
self.file_dialog.pick_file();
}
ui.label(format!("Picked file: {:?}", self.picked_file));
// 更新对话框
self.file_dialog.update(ctx);
// 检查用户是否选择了文件
if let Some(path)极速版
if let Some(path) = self.file_dialog.take_picked() {
self.picked_file = Some(path.to_path_buf());
}
});
}
}
fn main() -> eframe::Result<()> {
eframe::run_native(
"File dialog demo",
eframe::NativeOptions::default(),
Box::new(|ctx| Ok(Box::new(MyApp::new(ctx)))),
)
}
完整示例代码
下面是一个更完整的示例,展示了如何自定义文件对话框:
use std::path::PathBuf;
use std::sync::Arc;
use eframe::egui;
use egui_file_dialog::FileDialog;
struct MyApp {
file_dialog: FileDialog,
picked_file: Option<PathBuf>,
show_file_dialog: bool,
}
impl MyApp {
pub fn new(_cc: &eframe::CreationContext) -> Self {
let mut file_dialog = FileDialog::new()
.initial_directory(PathBuf::from("."))
.default_size([800.0, 600.0])
.resizable(true)
.show_new_folder_button(true)
.show_search(true)
.add_quick_access("Workspace", |s| {
s.add_path("📁 Documents", "Documents");
s.add_path("📁 Downloads", "Downloads");
})
.set_file_icon(
"📄",
Arc::new(|path| path.extension().unwrap_or_default() == "txt"),
)
.add_file_filter(
"Text files",
Arc::new(|p| p.extension().unwrap_or_default() == "txt"),
)
.add_file_filter(
"All files",
Arc::new(|_| true),
);
Self {
file_dialog,
picked_file: None,
show_file_dialog: false,
}
}
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
if ui.button("打开文件对话框").clicked() {
self.show_file_dialog = true;
self.file_dialog.pick_file();
}
if ui.button("保存文件").clicked() {
self.show_file_dialog = true;
self.file_dialog.save_file();
}
ui.label(format!("选择的文件: {:?}", self.picked_file));
if self.show_file_dialog {
// 更新对话框
self.file_dialog.update(ctx);
// 检查用户是否选择了文件
if let Some(path) = self.file_dialog.take_picked() {
self.picked_file = Some(path.to_path_buf());
self.show_file_dialog = false;
}
// 检查用户是否取消了对话框
if self.file_dialog.canceled() {
self.show_file_dialog = false;
}
}
});
}
}
fn main() -> eframe::Result<()> {
eframe::run_native(
"文件对话框示例",
eframe::NativeOptions::default(),
Box::new(|ctx| Ok(Box::new(MyApp::new(ctx)))),
)
}
键盘快捷键
文件对话框支持以下键盘快捷键:
名称 | 描述 | 默认值 |
---|---|---|
submit | 提交当前操作或打开当前选中的文件夹 | Enter |
cancel | 取消当前操作 | Escape |
parent | 打开父目录 | ALT + ↑ |
back | 后退 | Mouse button 1, ALT + ←, Backspace |
forward | 前进 | Mouse button 2, ALT + → |
reload | 重新加载文件对话框数据和当前打开的目录 | F5 |
new_folder | 打开创建新文件夹的对话框 | CTRL + N (Linux/Windows), CMD + N (macOS) |
edit_path | 文本编辑当前路径 | / |
home_edit_path | 打开主目录并开始文本编辑路径 | ~ |
selection_up | 将选择向上移动一项 | ↑ |
selection_down | 将选择向下移动一项 | ↓ |
select_all | 当使用文件对话框选择多个文件和文件夹时,选择目录中的所有项目 | CTRL + A (Linux/Windows), CMD + A (macOS) |
多语言支持
文件对话框的标签可以自定义以支持不同语言:
use egui_file_dialog::{FileDialog, FileDialogLabels};
enum Language {
English,
Chinese,
}
fn get_labels_chinese() -> FileDialogLabels {
FileDialogLabels {
title_select_directory: "📁 打开文件夹".to_string(),
title_select_file: "📂 打开文件".to_string(),
title_save_file: "💾 保存文件".to_string(),
button_open: "打开".to_string(),
button_save: "保存".to_string(),
button_cancel: "取消".to_string(),
label_name: "名称".to_string(),
label_size: "大小".to_string(),
label_modified: "修改日期".to_string(),
..Default::default()
}
}
fn update_labels(language: &Language, file_dialog: &mut FileDialog) {
*file_dialog.labels_mut() = match language {
Language::English => FileDialogLabels::default(),
Language::Chinese => get_labels_chinese(),
};
}
持久化数据
如果需要保存用户设置(如固定文件夹、显示隐藏文件等),可以使用FileDialogStorage
:
use egui_file_dialog::FileDialog;
struct MyApp {
file_dialog: FileDialog,
}
impl MyApp {
pub fn new(cc: &eframe::CreationContext) -> Self {
let mut file_dialog = FileDialog::default();
// 加载文件对话框的持久化数据
if let Some(storage) = cc.storage {
*file_dialog.storage_mut() =
eframe::get_value(storage, "file_dialog_storage").unwrap_or_default()
}
Self { file_dialog }
}
}
impl eframe::App for MyApp {
fn save(&mut self, storage: &mut dyn eframe::Storage) {
// 保存文件对话框的持久化数据
eframe::set_value(
storage,
"file_dialog_storage",
self.file_dialog.storage_mut(),
);
}
// ...其他实现
}
1 回复
egui-file-dialog:轻量级跨平台GUI文件选择器
简介
egui-file-dialog是一个轻量级的Rust文件对话框库,专为EGUI框架设计。它提供了跨平台的文件选择功能,可以轻松集成到你的EGUI应用程序中。
主要特性
- 轻量级实现
- 跨平台支持
- 与EGUI无缝集成
- 支持文件和目录选择
- 可自定义的界面
完整示例代码
下面是一个完整的示例,展示了如何使用egui-file-dialog创建一个简单的文件选择器应用:
use eframe::egui;
use egui_file_dialog::FileDialog;
// 定义应用结构体
struct MyApp {
file_dialog: FileDialog,
selected_file: Option<String>,
selected_files: Vec<String>,
selected_dir: Option<String>,
}
impl MyApp {
fn new() -> Self {
Self {
file_dialog: FileDialog::new()
.default_directory("~") // 设置初始目录
.add_filter("图像文件", &["png", "jpg", "jpeg"])
.add_filter("文本文件", &["txt", "md"]),
selected_file: None,
selected_files: Vec::new(),
selected_dir: None,
}
}
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
// 设置自定义样式
let mut style = (*ctx.style()).clone();
style.visuals.widgets.inactive.bg_fill = egui::Color32::from_rgb(25, 25, 25);
ctx.set_style(style);
// 主面板
egui::CentralPanel::default().show(ctx, |ui| {
// 选择单个文件按钮
if ui.button("选择文件").clicked() {
self.file_dialog.select_file();
}
// 选择多个文件按钮
if ui.button("选择多个文件").clicked() {
self.file_dialog.multiple_files(true).select_file();
}
// 选择目录按钮
if ui.button("选择目录").clicked() {
self.file_dialog.select_directory();
}
// 更新文件对话框状态并获取选择结果
if let Some(path) = self.file_dialog.update(ctx).selected() {
self.selected_file = Some(path.display().to_string());
}
// 显示选择的文件或目录
if let Some(file) = &self.selected_file {
ui.label(format!("已选择文件: {}", file));
}
if let Some(dir) = &self.selected_dir {
ui.label(format!("已选择目录: {}", dir));
}
if !self.selected_files.is_empty() {
ui.label("已选择多个文件:");
for file in &self.selected_files {
ui.label(format!("- {}", file));
}
}
});
}
}
fn main() {
// 创建原生选项
let options = eframe::NativeOptions {
initial_window_size: Some(egui::vec2(400.0, 300.0)),
..Default::default()
};
// 运行应用
eframe::run_native(
"文件选择器示例",
options,
Box::new(|_cc| Box::new(MyApp::new())),
);
}
使用说明
- 首先确保在
Cargo.toml
中添加了必要的依赖:
[dependencies]
egui-file-dialog = "0.3"
egui = "0.24"
eframe = "0.24"
- 这个示例展示了如何:
- 创建基本的文件选择对话框
- 设置初始目录
- 添加文件类型过滤器
- 选择单个文件
- 选择多个文件
- 选择目录
- 自定义界面样式
-
运行应用后,你将看到一个简单的窗口,包含三个按钮分别用于选择文件、选择多个文件和选择目录。
-
选择结果会显示在窗口下方。
注意事项
- 确保在应用程序的主循环中调用
file_dialog.update(ctx)
- 文件对话框是模态的,打开时会阻止与其他UI元素的交互
- 在移动平台上可能需要额外的权限配置