Rust窗口文件对话框库wfd的使用,wfd提供跨平台文件选择、目录浏览和保存对话框功能

Rust窗口文件对话框库wfd的使用,wfd提供跨平台文件选择、目录浏览和保存对话框功能

wfd是一个简单易用的Rust库,提供了对Windows API中打开和保存对话框的抽象,支持GNU和MSVC工具链,并且依赖极少。

示例代码

标准打开对话框

let dialog_result = wfd::open_dialog(Default::default())?;

文件夹选择对话框

use wfd::{DialogParams};

let params = DialogParams {
    options: FOS_PICKFOLDERS,
    .. Default::default()
};

let dialog_result = wfd::open_dialog(params)?;

带有自定义文件扩展名过滤器的保存对话框

use wfd::{DialogParams};

let params = DialogParams {
    title: "Select an image to open",
    file_types: vec![("JPG Files", "*.jpg;*.jpeg"), ("PNG Files", "*.png"), ("Bitmap Files", "*.bmp")],
    default_extension: "jpg",
    ..Default::default()
};

let dialog_result = wfd::save_dialog(params)?;

完整示例

下面是一个完整的示例程序,展示了如何使用wfd库实现文件选择、目录浏览和保存对话框功能:

use wfd::{DialogParams, FOS_PICKFOLDERS};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 标准文件选择对话框
    let open_result = wfd::open_dialog(Default::default())?;
    println!("选择的文件: {:?}", open_result.selected_file_path);
    
    // 2. 文件夹选择对话框
    let folder_params = DialogParams {
        options: FOS_PICKFOLDERS,
        ..Default::default()
    };
    let folder_result = wfd::open_dialog(folder_params)?;
    println!("选择的文件夹: {:?}", folder_result.selected_file_path);
    
    // 3. 保存文件对话框
    let save_params = DialogParams {
        title: "保存图片",
        file_types: vec![
            ("JPG Files", "*.jpg;*.jpeg"), 
            ("PNG Files", "*.png"), 
            ("Bitmap Files", "*.bmp")
        ],
        default_extension: "jpg",
        ..Default::default()
    };
    let save_result = wfd::save_dialog(save_params)?;
    println!("保存路径: {:?}", save_result.selected_file_path);
    
    Ok(())
}

要使用wfd库,请在你的Cargo.toml中添加以下依赖:

[dependencies]
wfd = "0.1.7"

wfd库提供了跨平台的文件对话框功能,支持Windows系统,使用简单且依赖少,非常适合需要文件选择功能的Rust应用程序开发。


1 回复

Rust窗口文件对话框库wfd使用指南

wfd是一个轻量级的Rust库,提供了跨平台的文件对话框功能,包括文件选择、目录浏览和保存对话框。它支持Windows、macOS和Linux平台。

安装

在Cargo.toml中添加依赖:

[dependencies]
wfd = "0.1"

基本用法

1. 打开文件对话框

use wfd::open_file_dialog;

fn main() {
    let result = open_file_dialog(
        "选择文件",  // 对话框标题
        "",         // 初始目录(空表示默认)
        None,       // 文件过滤器(可选)
    );
    
    match result {
        Some(path) => println!("选择的文件: {}", path),
        None => println!("用户取消了选择"),
    }
}

2. 打开多文件选择对话框

use wfd::open_multiple_files_dialog;

fn main() {
    let result = open_multiple_files_dialog(
        "选择多个文件",
        "",
        Some(vec![("文本文件", "*.txt"), ("图片", "*.png;*.jpg")]),
    );
    
    if let Some(files) = result {
        println!("选择了 {} 个文件:", files.len());
        for file in files {
            println!("- {}", file);
        }
    }
}

3. 保存文件对话框

use wfd::save_file_dialog;

fn main() {
    let result = save_file_dialog(
        "保存文件",
        "",
        Some(vec![("文本文件", "*.txt"), ("所有文件", "*.*")]),
    );
    
    if let Some(path) = result {
        println!("将保存到: {}", path);
        // 这里可以添加文件保存逻辑
    }
}

4. 选择目录对话框

use wfd::pick_folder_dialog;

fn main() {
    let result = pick_folder_dialog(
        "选择目录",
        "",  // 初始目录
    );
    
    if let Some(dir) = result {
        println!("选择的目录: {}", dir);
    }
}

高级用法

自定义文件过滤器

use wfd::open_file_dialog;

fn main() {
    let filters = vec![
        ("Rust文件", "*.rs"),
        ("配置文件", "*.toml;*.json"),
        ("所有文件", "*.*"),
    ];
    
    let result = open_file_dialog("选择Rust文件", "", Some(filters));
    // ...
}

设置初始目录

use wfd::open_file_dialog;
use std::path::PathBuf;

fn main() {
    let initial_dir = PathBuf::from("/path/to/your/directory");
    let result = open_file_dialog(
        "选择文件",
        initial_dir.to_str().unwrap(),
        None,
    );
    // ...
}

注意事项

  1. 在Linux系统上,wfd依赖于zenitykdialog等工具,请确保系统已安装这些工具
  2. 对话框的外观和行为可能因操作系统而异
  3. 路径返回的是字符串形式,可以使用std::path::PathBuf进行进一步处理

wfd库提供了简单直观的API,适合需要基本文件对话框功能而不想引入复杂GUI框架的Rust应用程序。

完整示例demo

下面是一个整合了所有功能的完整示例:

use wfd::{open_file_dialog, open_multiple_files_dialog, save_file_dialog, pick_folder_dialog};
use std::path::PathBuf;

fn main() {
    println!("=== 文件对话框示例 ===");
    
    // 1. 打开单个文件
    single_file_example();
    
    // 2. 打开多个文件
    multiple_files_example();
    
    // 3. 保存文件
    save_file_example();
    
    // 4. 选择目录
    pick_folder_example();
}

fn single_file_example() {
    println!("\n1. 选择单个文件:");
    let result = open_file_dialog(
        "请选择一个文件",
        "",
        Some(vec![
            ("文本文件", "*.txt"),
            ("图片文件", "*.png;*.jpg;*.jpeg"),
        ]),
    );
    
    match result {
        Some(path) => println!("选择的文件: {}", path),
        None => println!("用户取消了选择"),
    }
}

fn multiple_files_example() {
    println!("\n2. 选择多个文件:");
    let result = open_multiple_files_dialog(
        "请选择多个文件",
        "",
        Some(vec![
            ("Rust文件", "*.rs"),
            ("配置文件", "*.toml;*.json"),
        ]),
    );
    
    if let Some(files) = result {
        println!("选择了 {} 个文件:", files.len());
        for file in files {
            println!("- {}", file);
        }
    } else {
        println!("用户取消了选择");
    }
}

fn save_file_example() {
    println!("\n3. 保存文件:");
    let result = save_file_dialog(
        "保存文件",
        "",
        Some(vec![
            ("文本文件", "*.txt"),
            ("Markdown文件", "*.md"),
            ("所有文件", "*.*"),
        ]),
    );
    
    if let Some(path) = result {
        println!("文件将保存到: {}", path);
        // 这里可以添加实际的保存逻辑
    } else {
        println!("用户取消了保存");
    }
}

fn pick_folder_example() {
    println!("\n4. 选择目录:");
    
    // 设置初始目录为当前用户的文档目录
    let initial_dir = dirs::document_dir()
        .and_then(|p| p.to_str().map(|s| s.to_string()))
        .unwrap_or_default();
    
    let result = pick_folder_dialog(
        "请选择一个目录",
        &initial_dir,
    );
    
    if let Some(dir) = result {
        println!("选择的目录: {}", dir);
    } else {
        println!("用户取消了选择");
    }
}

要运行这个完整示例,需要在Cargo.toml中添加两个依赖项:

[dependencies]
wfd = "0.1"
dirs = "4.0"  # 用于获取系统标准目录路径

这个示例展示了:

  1. 如何打开单个文件选择对话框
  2. 如何打开多文件选择对话框
  3. 如何使用保存文件对话框
  4. 如何选择目录并设置初始目录
  5. 如何处理用户取消操作的情况
  6. 如何使用不同类型的文件过滤器

每个功能都封装在单独的函数中,便于理解和重用。

回到顶部