7 个版本 (破坏性更新)

0.6.0 2024 年 7 月 3 日
0.5.0 2024 年 3 月 30 日
0.4.0 2024 年 2 月 29 日
0.3.1 2024 年 2 月 20 日
0.1.0 2024 年 2 月 3 日

#182 in GUI

Download history 15/week @ 2024-05-03 24/week @ 2024-05-10 65/week @ 2024-05-17 46/week @ 2024-05-24 33/week @ 2024-05-31 63/week @ 2024-06-07 141/week @ 2024-06-14 46/week @ 2024-06-21 144/week @ 2024-06-28 139/week @ 2024-07-05 66/week @ 2024-07-12 120/week @ 2024-07-19 101/week @ 2024-07-26 66/week @ 2024-08-02 85/week @ 2024-08-09 100/week @ 2024-08-16

362 次每月下载
2 crates 中使用

MIT 许可

185KB
3.5K SLoC

egui-file-dialog

Latest version Documentation Dependency status Crates.io Total Downloads Total lines of code MIT

目录
  1. 特性
  2. 示例
  3. 快捷键
  4. 自定义
  5. 多语言支持
  6. 持久数据

此仓库提供了一个易于使用和可定制的文件对话框(即文件资源管理器、文件选择器),适用于 egui

该文件对话框旨在供桌面应用程序使用,允许在 egui 应用程序内直接使用文件对话框,而不依赖于操作系统的文件资源管理器。这也确保了文件对话框在所有平台上具有相同的样式和功能。

下一个版本中包含的最新更改可以在 develop 分支上的 CHANGELOG.md 文件中找到。

目前仅在 Linux 和 Windows 上进行了测试!

特性

  • 选择文件或目录
  • 保存文件(提示用户输入目标路径)
    • 询问用户是否覆盖现有文件的对话框
  • 一次性选择多个文件和文件夹(ctrl/shift + 点击)
  • 在正常或模态窗口中打开对话框
  • 创建新文件夹
  • 键盘导航
  • 显示或隐藏隐藏文件和文件夹的选项
  • 导航按钮以打开父目录或上一个目录
  • 在目录中搜索项目
  • 添加用户可以从下拉菜单选择的文件过滤器
  • 用户目录(主页、文档、...)和系统磁盘的快捷键
  • 将文件夹固定在左侧侧边栏
  • 通过文本手动编辑路径
  • 自定义突出显示
    • 自定义对话框的可见区域和功能
    • 自定义对话框使用的文本标签以启用多语言支持
    • 自定义文件和文件夹图标
    • 将自定义快速访问部分添加到左侧边栏
    • 自定义文件对话框使用的快捷键

示例

可以在 examples 文件夹中找到可运行的详细示例。

以下示例展示了使用 eframe 来选择文件的基本用法。

Cargo.toml

[dependencies]
eframe = "0.28.0"
egui-file-dialog = "0.6.0"

main.rs

use std::path::PathBuf;

use eframe::egui;
use egui_file_dialog::FileDialog;

struct MyApp {
    file_dialog: FileDialog,
    selected_file: Option<PathBuf>,
}

impl MyApp {
    pub fn new(_cc: &eframe::CreationContext) -> Self {
        Self {
            // Create a new file dialog object
            file_dialog: FileDialog::new(),
            selected_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("Select file").clicked() {
                // Open the file dialog to select a file.
                self.file_dialog.select_file();
            }

            ui.label(format!("Selected file: {:?}", self.selected_file));

            // Update the dialog
            self.file_dialog.update(ctx);

            // Check if the user selected a file.
            if let Some(path) = self.file_dialog.take_selected() {
                self.selected_file = Some(path.to_path_buf());
            }
        });
    }
}

fn main() -> eframe::Result<()> {
    eframe::run_native(
        "File dialog demo",
        eframe::NativeOptions::default(),
        Box::new(|ctx| Box::new(MyApp::new(ctx))),
    )
}

快捷键

可以在文件对话框中使用快捷键以方便导航。所有快捷键都可以通过后端使用 FileDialogKeyBindingsFileDialog::keybindings 进行配置。
以下表格列出了所有可用的快捷键及其默认值。

名称 描述 默认值
submit 提交当前操作或打开当前选定的文件夹 Enter
cancel 取消当前操作 Escape
parent 打开父目录 ALT +
back 后退 鼠标按钮1
ALT +
退格键
forward 前进 鼠标按钮2
ALT +
reload 重新加载文件对话框数据和当前打开的目录 F5
new_folder 打开对话框以创建新文件夹 CTRL + N
edit_path 文本编辑当前路径 /
home_edit_path 打开主目录并开始文本编辑路径 ~
selection_up 向上移动一个项目
selection_down 向下移动一个项目
select_all 在文件对话框中选择多个文件和文件夹时选择目录中的每个项目 CTRL + A

自定义

许多东西都可以自定义,以便在不同情况下使用对话框。
以下列出了一些自定义的亮点。有关所有可能的自定义选项,请参阅 docs.rs 上的文档。

  • 使用 FileDialog::show_* 方法设置对话框哪些区域和功能可见
  • 更新对话框使用的文本标签。参见 多语言支持
  • 使用 FileDialog::set_file_icon 自定义文件和文件夹图标(目前仅支持 unicode)
  • 使用 FileDialog::keybindings 自定义文件对话框使用的快捷键。参见 快捷键

由于对话框使用 egui 风格以使外观与应用程序的其余部分相似,因此可以使用 egui::Styleegui::Context::set_style 自定义外观。

以下示例展示了如何自定义单个文件对话框。
如果您需要使用相同或几乎相同的选项配置多个文件对话框对象,则使用 FileDialogConfigFileDialog::with_config 是一个好主意(有关 FileDialogConfig,请参阅 docs.rs)。

use std::path::PathBuf;
use std::sync::Arc;

use egui_file_dialog::FileDialog;

FileDialog::new()
    .initial_directory(PathBuf::from("/path/to/app"))
    .default_file_name("app.cfg")
    .default_size([600.0, 400.0])
    .resizable(false)
    .show_new_folder_button(false)
    .show_search(false)
    .show_path_edit_button(false)
    // Add a new quick access section to the left sidebar
    .add_quick_access("Project", |s| {
        s.add_path("☆  Examples", "examples");
        s.add_path("📷  Media", "media");
        s.add_path("📂  Source", "src");
    })
    // Markdown files should use the "document with text (U+1F5B9)" icon
    .set_file_icon(
        "🖹",
        Arc::new(|path| path.extension().unwrap_or_default() == "md"),
    )
    // .gitignore files should use the "web-github (U+E624)" icon
    .set_file_icon(
        "",
        Arc::new(|path| path.file_name().unwrap_or_default() == ".gitignore"),
    )
    // Add file filters the user can select in the bottom right
    .add_file_filter(
        "PNG files",
        Arc::new(|p| p.extension().unwrap_or_default() == "png"),
    )
    .add_file_filter(
        "Rust source files",
        Arc::new(|p| p.extension().unwrap_or_default() == "rs"),
    );

使用这些选项,对话框的外观如下:

以下配置可以生成最小的对话框

FileDialog::new()
    .title_bar(false)
    .show_top_panel(false)
    .show_left_panel(false)

多语言支持

对于桌面应用程序,通常需要提供不同的语言。虽然对话框目前默认只提供英文标签,但标签可以完全自定义。这使得可以将标签适应不同的语言。

以下示例显示了如何更改标签,以在英语或德语中显示文件对话框。
查看examples/multilingual获取完整示例。

use egui_file_dialog::{FileDialog, FileDialogLabels};

enum Language {
    English,
    German,
}

fn get_labels_german() -> FileDialogLabels {
    FileDialogLabels {
        title_select_directory: "📁 Ordner Öffnen".to_string(),
        title_select_file: "📂 Datei Öffnen".to_string(),
        title_save_file: "📥 Datei Speichern".to_string(),

        // ... See examples/multilingual for the other labels

        ..Default::default()
    }
}

/// Updates the labels of the file dialog.
/// Should be called every time the user selects a different language.
fn update_labels(language: &Language, file_dialog: &mut FileDialog) {
    *file_dialog.labels_mut() = match language {
        // English labels are used by default
        Language::English => FileDialogLabels::default(),
        // Use custom labels for German
        Language::German => get_labels_german(),
    };
}

持久数据

文件对话框目前需要以下持久数据在多个文件对话框对象间存储

  • 用户固定到左侧侧边栏的文件夹(FileDialog::show_pinned_folders
  • 如果隐藏文件和文件夹应该可见(FileDialog::show_hidden_option

如果上述功能之一被激活,应用应保存数据。否则,用户可能会遇到令人沮丧的情况,并且这些功能不会提供太多附加价值。

所有需要永久存储的数据都包含在FileDialogStorage结构体中。可以使用FileDialog::storageFileDialog::storage_mut来访问此结构体以保存或加载数据。
默认情况下,启用了serde功能,它实现了serde::Serializeserde::Deserialize,用于要保存的对象。然而,也可以在不启用此功能的情况下访问对象。

以下示例显示了如何在启用serde功能的情况下使用eframe保存数据。
查看examples/persistence获取完整示例。

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();

        // Load the persistent data of the file dialog.
        // Alternatively, you can also use the `FileDialog::storage` builder method.
        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) {
        // Save the persistent data of the file dialog
        eframe::set_value(
            storage,
            "file_dialog_storage",
            self.file_dialog.storage_mut(),
        );
    }
}

依赖项

~6–32MB
~477K SLoC