Files
VX5_KRO_GearPump/fileManage/U盘热拔插修复方案.md
T

124 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# U盘热拔插修复方案
## 问题描述
`FileManageWidget` 右侧 U 盘文件显示列表的 `udiskSelectBox` 下拉框无法处理热拔插的 U 盘。每次点击下拉框时,应能识别到当前已插入的 U 盘列表。
## 根因分析
### 1. 信号连接已存在(无需修改)
在 `FileManageWidget.ui` 中,`udiskSelectBox`(`UDiskComboBox` 类型)的 `popupShowed()` 信号已经连接到 `FileManageWidget::updateUDiskDevList()` 槽:
```xml
<connection>
<sender>udiskSelectBox</sender>
<signal>popupShowed()</signal>
<receiver>FileManageWidget</receiver>
<slot>updateUDiskDevList()</slot>
</connection>
```
`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 <QFile>
```
### 改动 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盘" |