# U盘热拔插修复方案 ## 问题描述 `FileManageWidget` 右侧 U 盘文件显示列表的 `udiskSelectBox` 下拉框无法处理热拔插的 U 盘。每次点击下拉框时,应能识别到当前已插入的 U 盘列表。 ## 根因分析 ### 1. 信号连接已存在(无需修改) 在 `FileManageWidget.ui` 中,`udiskSelectBox`(`UDiskComboBox` 类型)的 `popupShowed()` 信号已经连接到 `FileManageWidget::updateUDiskDevList()` 槽: ```xml udiskSelectBox popupShowed() FileManageWidget updateUDiskDevList() ``` `UDiskComboBox` 重写了 `showPopup()`,每次下拉框展开时都会发射 `popupShowed()` 信号: ```cpp void UDiskComboBox::showPopup() { emit popupShowed(); QComboBox::showPopup(); } ``` ### 2. 问题根源:`updateUDiskDevList()` 实现有缺陷 **旧代码:** ```cpp void FileManageWidget::updateUDiskDevList() { QDir dir(UDISK_DOC_ROOT_DIR); if(!dir.exists()) { ui->udiskSelectBox->clear(); return; } if(ui->udiskSelectBox->currentText() != tr("U盘")){ ui->udiskSelectBox->clear(); ui->udiskSelectBox->addItem(tr("U盘")); ui->udiskSelectBox->setCurrentIndex(0); } updateFileListView(ui->udiskFileListView); } ``` **两个问题:** 1. **`QDir::exists()` 不可靠**:`UDISK_DOC_ROOT_DIR`(`/udisk/doc/`)目录可能在 U 盘未挂载时也存在于根文件系统中,导致 `exists()` 始终返回 `true`,无法正确识别 U 盘的拔出。 2. **条件判断逻辑脆弱**:`if(currentText() != "U盘")` 的判断方式无法正确处理"拔出再插入"的完整热拔插场景。例如 U 盘拔出后下拉框被清空,再次插入时 `currentText()` 为空字符串,虽然能进入分支添加 "U盘",但整体逻辑不够健壮。 ## 修复方案 ### 修改文件 **文件路径:** `fileManage/FileManageWidget.cpp` ### 改动 1:新增头文件 ```cpp #include ``` ### 改动 2:重写 `updateUDiskDevList()` 方法 ```cpp void FileManageWidget::updateUDiskDevList() { bool hasUDisk = false; QFile mountsFile("/proc/mounts"); if (mountsFile.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&mountsFile); while (!in.atEnd()) { const QString line = in.readLine(); if (line.contains("/udisk ")) { hasUDisk = true; break; } } mountsFile.close(); } if (!hasUDisk) { QDir dir(UDISK_DOC_ROOT_DIR); hasUDisk = dir.exists(); } ui->udiskSelectBox->clear(); if (hasUDisk) { ui->udiskSelectBox->addItem(tr("U盘")); ui->udiskSelectBox->setCurrentIndex(0); } updateFileListView(ui->udiskFileListView); } ``` ### 新逻辑说明 | 步骤 | 说明 | |------|------| | 1. 读取 `/proc/mounts` | 检查 `/udisk` 挂载点是否真正挂载了设备(Linux 下判断挂载状态的标准方式) | | 2. 回退检查 | 如果 `/proc/mounts` 读取失败,回退到 `QDir::exists()` 作为兼容性保障 | | 3. 重建下拉框 | 每次调用都先清空再根据检测结果添加 "U盘" 项,确保状态始终正确 | | 4. 刷新文件列表 | 调用 `updateFileListView()` 更新 U 盘文件显示 | ### 行为对照 | 场景 | 修复前 | 修复后 | |------|--------|--------| | U 盘插入 → 点击下拉框 | 可能不显示(目录始终存在) | 通过 `/proc/mounts` 检测到挂载,显示 "U盘" | | U 盘拔出 → 点击下拉框 | 仍显示 "U盘"(目录仍存在) | 检测到 `/udisk` 未挂载,下拉框为空 | | U 盘拔出再插入 → 点击下拉框 | 状态不确定 | 正确检测到重新挂载,显示 "U盘" | | 系统启动时无 U 盘 | 可能显示 "U盘" | 下拉框为空 | | 系统启动时有 U 盘 | 显示 "U盘" | 显示 "U盘" |