You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QML如何遍历指定目录下所有子文件夹获取指定格式音频文件

QML车载播放器U盘全目录音频扫描实现方案

你现有代码的问题在于:FolderListModel默认仅支持读取单级目录内容,不会递归遍历子文件夹,且你配置的根路径为当前运行目录./,没有指向U盘挂载路径,按以下步骤修改即可实现需求:

步骤1:修改基础属性配置

替换你原有playLogic下的items属性,新增自定义播放列表和U盘根路径配置:

Item {
    id: playLogic
    property int index: -1
    property MediaPlayer mediaPlayer: player
    // 新增:存储所有递归扫描到的音频文件路径
    property var playList: []
    // 替换为你的U盘实际挂载路径,测试时可先写死,后续可扩展自动识别
    property string usbRootPath: "/media/orangepi/你的U盘名称"
    // 根目录扫描模型
    property FolderListModel rootFolder: FolderListModel {
        folder: usbRootPath
        nameFilters: ["*.mp3", "*.ogg", "*.wav", "*.flac", "*.aac"] // 可按需新增支持的音频格式
        showDirs: true // 必须开启才能识别子文件夹
        showDotAndDotDot: false // 过滤系统默认的.和..目录
        sortField: FolderListModel.Name
    }

步骤2:新增递归扫描函数

在playLogic内新增递归遍历文件夹的逻辑:

// 递归扫描指定路径下的所有音频文件
function scanFolder(folderPath) {
    let tempScanModel = FolderListModel {
        folder: folderPath
        nameFilters: rootFolder.nameFilters
        showDirs: true
        showDotAndDotDot: false
    }
    // 等待目录加载完成后处理
    tempScanModel.onStatusChanged: {
        if (tempScanModel.status === FolderListModel.Ready) {
            for (let i = 0; i < tempScanModel.count; i++) {
                const isDir = tempScanModel.get(i, "isDir")
                const filePath = tempScanModel.get(i, "filePath")
                if (!isDir) {
                    // 是音频文件就加入播放列表
                    playList.push(filePath)
                } else {
                    // 是文件夹就递归扫描
                    scanFolder(filePath)
                }
            }
            // 根目录扫描完成触发回调
            if (folderPath === usbRootPath) {
                console.log("U盘扫描完成,共找到音频:" + playList.length + " 首")
                // 扫描完成后初始化播放
                if (playList.length > 0) setIndex(0)
            }
        }
    }
}

步骤3:修改原有播放逻辑适配新的播放列表

替换原有setIndex和init函数:

function init(){
    playList = [] // 每次初始化先清空旧的播放列表
    scanFolder(usbRootPath) // 触发U盘扫描
    // 原有播放状态控制逻辑保留
    if(mediaPlayer.playbackState===1){
        mediaPlayer.pause();
    }else if(mediaPlayer.playbackState===2){
        mediaPlayer.play();
    }
}

function setIndex(i)
{
    index = i;
    if (index < 0 || index >= playList.length)
    {
        index = -1;
        mediaPlayer.source = "";
    }
    else{
        mediaPlayer.source = playList[index];
        mediaPlayer.play();
    }
}

原有next、previous函数和Connections逻辑无需修改,可直接复用。

注意事项

  • 如果需要自动识别U盘避免写死路径,可在C++层实现U盘热插拔监听,将挂载路径信号抛到QML层赋值给usbRootPath即可;也可以用QProcess执行ls /media/$USER命令读取当前挂载的U盘目录自动匹配。
  • 扫描逻辑是异步实现的,不会阻塞UI界面,大量音频文件扫描时也不会卡顿。
  • 你可以根据需求在nameFilters数组里新增支持的音频格式后缀。

内容的提问来源于stack exchange,提问作者Emad Deve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 23:06:02