Qt文件管理器实战:QFileSystemModel与QTreeView工程解析
简介这是一份面向QT初学者与C GUI开发入门者的轻量级文件管理器项目源码基于QT框架实现帮助读者理解桌面端文件管理工具的基本架构与交互逻辑。压缩包共33个文件约80KB包含8个cpp源文件、7个h头文件、4个ui界面文件以及qrc资源文件、pro工程文件和若干png图标素材覆盖主窗口、文件视图、重命名与图片文本对话框、后台文件线程及自定义文本编辑组件等模块。项目通过MainWindow组织菜单与工作区借助FileThread将复制粘贴等I/O操作放入后台线程避免界面阻塞并利用自定义视图与对话框完成缩略图浏览、文本预览和重命名交互结构清晰、体量小巧适合作为QT多线程与界面组件协同开发的练手案例。目前已有201人学习下载可帮助读者快速掌握QT工程组织方式、信号槽机制与异步文件操作思路。1. 从一堆散落文件到能跑起来的工程QT 简易文件管理器到底给了什么下载过一堆 Qt 练手项目的人大概都有这种体验压缩包解压出来.pro文件、main.cpp、几个.ui文件散在目录里双击.pro用 Qt Creator 打开编译按钮一点报错刷满整个面板。这个「QT 简易文件管理器.zip」就是典型的这类资源——它不是教程不是视频课而是一个可以直接打开、编译、运行的完整工程包。核心功能围绕文件系统操作展开目录树浏览、文件列表展示、新建/删除/重命名、复制粘贴、路径导航基本覆盖了 Qt Widgets 入门到进阶的常见控件和模型视图用法。适合两类人一是刚学完 Qt 基础语法、想找个完整项目练手的二是需要快速搭一个文件管理类工具原型、不想从零写 UI 的。它解决的不是「教你 Qt 语法」的问题而是「给你一个能跑、能改、能拆的骨架」。2. 拆开工程看骨架QFileSystemModel 与 QTreeView 的配合逻辑拿到压缩包之后别急着编译。先花十分钟把目录结构和核心文件过一遍后面改代码和排错会省很多时间。这个项目的技术栈是纯 Qt Widgets没有引入第三方库构建系统用的是 qmake.pro文件不是 CMake。这意味着它对 Qt 版本的要求比较宽松Qt 5.x 和 Qt 6.x 都能尝试但需要注意 Qt 6 里部分 API 有变动。2.1 工程文件结构与模块划分解压后典型的结构大致是这样SimpleFileManager/ ├── SimpleFileManager.pro ├── main.cpp ├── mainwindow.h ├── mainwindow.cpp ├── mainwindow.ui ├── fileoperations.h ├── fileoperations.cpp └── resources/ └── icons/.pro文件里通常只声明QT core gui widgets没有多余的模块依赖。mainwindow.ui是 Qt Designer 生成的界面描述文件里面定义了主窗口的布局左侧是QTreeView用来显示目录树右侧是QListView或QTableView显示当前目录下的文件列表顶部有地址栏QLineEdit和几个操作按钮。注意如果你拿到的版本里.ui文件缺失或者损坏Qt Creator 会提示无法加载界面。这时候可以检查.pro里是否有FORMS mainwindow.ui以及文件是否真的存在于对应路径。2.2 QFileSystemModel 的挂载与过滤参数这个项目最核心的技术点就是QFileSystemModel的使用。它是 Qt 提供的一个现成模型类直接把本地文件系统映射成树形结构配合QTreeView就能实现目录浏览不需要自己写递归遍历。// mainwindow.cpp 中初始化模型和视图的典型写法 m_fileSystemModel new QFileSystemModel(this); m_fileSystemModel-setRootPath(QDir::currentPath()); // 设置根路径 m_fileSystemModel-setFilter(QDir::NoDotAndDotDot | QDir::AllDirs); // 只显示目录 ui-treeView-setModel(m_fileSystemModel); ui-treeView-setRootIndex(m_fileSystemModel-index(QDir::currentPath())); // 隐藏不需要的列只保留名称列 for (int i 1; i m_fileSystemModel-columnCount(); i) { ui-treeView-hideColumn(i); }这里有几个参数值得说清楚。setRootPath()决定了树的起点一般设成当前工作目录或者用户主目录。setFilter()里的QDir::NoDotAndDotDot是去掉.和..这两个特殊目录项QDir::AllDirs表示只显示目录不显示文件——因为文件列表由右侧视图单独负责。如果你想让左侧树也显示文件把 filter 改成QDir::AllDirs | QDir::Files就行但界面会显得很杂。hideColumn()那段是因为QFileSystemModel默认返回四列名称、大小、类型、修改日期。目录树只需要名称列其余三列隐藏掉界面才干净。2.3 右侧文件列表的模型切换与信号连接右侧文件列表通常有两种实现方式一种是用另一个QFileSystemModel实例另一种是用QDir手动遍历后填充QListWidget。这个项目用的是前者因为代码量更少。// 右侧列表使用同一个模型的另一个视图 ui-listView-setModel(m_fileSystemModel); ui-listView-setRootIndex(m_fileSystemModel-index(QDir::currentPath())); // 点击左侧目录树时右侧列表跟随切换 connect(ui-treeView, QTreeView::clicked, this, [this](const QModelIndex index) { QString path m_fileSystemModel-filePath(index); ui-listView-setRootIndex(m_fileSystemModel-index(path)); ui-lineEditPath-setText(path); // 同步更新地址栏 });信号槽的连接是整个交互逻辑的骨架。QTreeView::clicked信号携带被点击项的QModelIndex通过filePath()拿到实际路径再把右侧视图的根索引切过去。地址栏同步更新是为了让用户知道当前在哪个目录下。提示如果点击目录后右侧列表没反应先检查connect是否返回了true再确认filePath()拿到的路径是否有效。常见原因是模型还没加载完成就触发了点击。3. 编译与运行从 qmake 到可执行文件的完整链路工程能打开不代表能编译通过。Qt 项目的编译环境依赖比较重尤其是跨版本的时候。这一章把编译流程和常见报错处理讲清楚照着走基本能跑起来。3.1 环境准备与 Qt 版本选择先确认本机装了什么版本的 Qt。打开 Qt Creator在「帮助 → 关于 Qt Creator」里能看到版本号但更准确的方式是看 Kit 配置。工具 → 选项 → Kits里会列出可用的编译器、Qt 版本和调试器组合。组件推荐版本说明Qt5.15.x LTS兼容性最好qmake 项目首选Qt6.2可用但需注意 API 变动编译器MinGW 64-bitWindows 下最省事编译器MSVC 2019需要装 Visual Studio Build Tools构建系统qmake项目自带 .pro不需要 CMake如果本机只装了 Qt 6打开项目时 Qt Creator 会提示是否要执行版本迁移。建议先点「否」手动检查代码里有没有 Qt 6 已废弃的 API。3.2 编译步骤与常见报错处理标准流程是打开 Qt Creator → 文件 → 打开文件或项目 → 选中.pro文件 → 选择 Kit → 点击构建CtrlB→ 点击运行CtrlR。# 如果你习惯命令行编译qmake 的流程是这样的 cd SimpleFileManager qmake SimpleFileManager.pro # 生成 Makefile make # Linux/macOS 下编译 # 或者 Windows MinGW mingw32-make命令行编译的好处是报错信息更完整不会被 IDE 的输出面板截断。qmake那一步如果报「Cannot find file」之类的错说明当前目录不对或者.pro文件名和实际不一致。编译阶段最常见的三类报错第一类是fatal error: QFileSystemModel: No such file or directory。这说明.pro里没有加QT widgets或者 Kit 选错了。QFileSystemModel属于 Qt Widgets 模块不是 Qt Core。第二类是undefined reference to vtable for MainWindow。这是链接错误通常是因为.h文件里声明了虚函数但没有对应的实现或者mainwindow.cpp没有被加入编译。检查.pro里的SOURCES和HEADERS列表是否完整。第三类是中文乱码。Qt 5 默认用 UTF-8 处理源码但如果源文件保存成了 GBK 编码界面上的中文就会变成乱码。解决办法是在.pro里加一行QMAKE_CXXFLAGS -finput-charsetUTF-8或者把所有源文件统一转成 UTF-8 无 BOM 格式。3.3 运行后的功能验证清单编译通过、程序启动之后按下面这个清单逐项验证功能是否正常左侧目录树能否正常展开和折叠根节点是否指向预期路径点击左侧任意目录右侧列表是否同步切换地址栏显示的路径是否和实际点击的目录一致新建文件夹按钮是否能在当前目录下创建新目录删除操作是否有确认提示删除后列表是否刷新重命名功能是否支持重名时是否有处理如果某一项不通过先定位是 UI 信号没连上还是底层文件操作函数返回了错误。这个项目的文件操作部分一般封装在fileoperations.cpp里用QDir、QFile、QFileInfo这些类实现出错时会通过QMessageBox弹提示。4. 避坑与排查五个让新手卡半天的真实问题这一章记录的是我在拆这类 Qt 文件管理器项目时反复遇到的坑。每一条都按「现象 → 原因 → 解决」写方便对号入座。4.1 现象编译通过但运行闪退没有任何提示原因最常见的情况是main.cpp里创建MainWindow对象时用了栈上分配但窗口的父对象设置有问题或者某个成员指针在使用前没有初始化。另一个高频原因是.ui文件里的控件名称和代码里ui-xxx引用的名称不一致运行时访问空指针。解决在main.cpp的QApplication a(argc, argv);后面加断点单步跟到MainWindow w; w.show();这两行。如果闪退发生在w.show()之前问题在构造函数里如果在之后问题在showEvent或某个延迟初始化的逻辑里。用 Qt Creator 的调试模式跑一遍调用栈会直接指向出问题的行。4.2 现象目录树加载极慢点一下卡好几秒原因QFileSystemModel默认会在后台线程里递归扫描目录如果根路径设成了某个包含大量文件的盘符根目录比如整个 C 盘首次加载会非常慢。另外如果同时设置了setFilter(QDir::AllDirs | QDir::Files)模型需要索引的文件数量会翻好几倍。解决把setRootPath()设成一个具体的、文件数量可控的目录比如用户主目录或者项目所在目录。如果确实需要浏览整个盘符可以在.pro里开启QFileSystemModel的延迟加载特性或者改用QDirModel虽然已废弃但加载策略不同。更彻底的做法是自己用QDirIterator做懒加载只展开当前可见层级。4.3 现象删除文件后列表没刷新被删的文件还在原因QFileSystemModel虽然有文件系统监控机制但在某些平台上尤其是 Windows监控信号有延迟或者被其他操作阻塞了。如果删除操作是通过QFile::remove()直接执行的模型不一定能立刻感知到变化。解决在执行删除、重命名、新建等写操作之后手动调用一次模型的刷新。简单粗暴的方式是重新setRootIndex()更优雅的方式是用QFileSystemModel::setRootPath()重新触发一次索引。如果项目里用的是QListWidget手动填充的方式那就直接重新遍历目录刷新列表。// 删除操作后强制刷新模型 bool ok QFile::remove(filePath); if (ok) { // 方式一重新设置根索引触发刷新 QString currentPath m_fileSystemModel-filePath(ui-listView-rootIndex()); ui-listView-setRootIndex(m_fileSystemModel-index(currentPath)); }4.4 现象中文路径下文件操作失败提示「文件不存在」原因Windows 下QFile和QDir对中文路径的处理依赖系统编码。如果源码文件本身是 UTF-8但系统区域设置是 GBK路径字符串在传递过程中可能出现编码转换错误。Qt 5 默认把QString按 UTF-16 处理但和底层 Win32 API 交互时会经过一次转换。解决确保所有涉及路径的字符串都用QString而不是char*或std::string。如果必须用标准库字符串用QString::toLocal8Bit()转换后再传给文件操作函数。另外在main.cpp里加一行QTextCodec::setCodecForLocale(QTextCodec::codecForName(UTF-8));Qt 5 适用Qt 6 里这个 API 已经移除改用QStringConverter。4.5 现象换到 Qt 6 编译一堆 API 报废弃警告甚至报错原因Qt 6 移除或重命名了不少 Qt 5 的 API。在这个项目里常见的有QDesktopWidget被废弃、QRegExp换成QRegularExpression、QString::split的行为有微调、QFileSystemModel的部分信号签名变了。解决先看报错信息里提到的具体类和函数去 Qt 官方文档查对应的 Qt 6 替代方案。如果改动量太大最省事的办法是装一个 Qt 5.15 的 Kit用 qmake 直接编译。Qt 5.15 是 LTS 版本官方维护周期长跑这类老项目最稳。5. 进阶改造把文件管理器从「能跑」推到「好用」工程跑起来只是起点。这个项目的价值在于它的骨架足够简单方便在上面加东西。下面说几个我实际改过的方向以及改造时需要注意的技术细节。5.1 加一个文件搜索框QSortFilterProxyModel 的用法最实用的改造之一是加搜索过滤。QFileSystemModel本身不支持过滤但可以套一层QSortFilterProxyModel。// 在 MainWindow 构造函数里加代理模型 m_proxyModel new QSortFilterProxyModel(this); m_proxyModel-setSourceModel(m_fileSystemModel); m_proxyModel-setFilterCaseSensitivity(Qt::CaseInsensitive); // 忽略大小写 m_proxyModel-setRecursiveFilteringEnabled(true); // 递归过滤子目录 ui-listView-setModel(m_proxyModel); // 搜索框文本变化时更新过滤规则 connect(ui-lineEditSearch, QLineEdit::textChanged, this, [this](const QString text) { m_proxyModel-setFilterFixedString(text); });setRecursiveFilteringEnabled(true)是关键参数。不加这行的话过滤只作用于当前层级子目录里的匹配文件不会显示。加上之后搜索会递归整个子树但代价是文件多的时候会有性能损耗。如果目录规模很大建议加一个防抖定时器用户停止输入 300ms 后再触发过滤。5.2 右键菜单与文件操作QMenu 和 QAction 的挂载原项目如果只有按钮操作用起来会有点别扭。加一个右键菜单能明显提升操作效率。// 在 MainWindow 里重写 contextMenuEvent void MainWindow::contextMenuEvent(QContextMenuEvent *event) { QMenu menu(this); QAction *newDirAction menu.addAction(新建文件夹); QAction *renameAction menu.addAction(重命名); QAction *deleteAction menu.addAction(删除); menu.addSeparator(); QAction *copyPathAction menu.addAction(复制路径); QAction *selected menu.exec(event-globalPos()); if (selected newDirAction) { // 调用新建目录逻辑 } else if (selected deleteAction) { // 调用删除逻辑注意加确认对话框 } // 其余分支类似 }contextMenuEvent是QWidget的虚函数重写之后在窗口任意位置右键都会触发。menu.exec()是阻塞式的返回用户选中的QAction指针。注意event-globalPos()在 Qt 6 里改成了event-globalPosition().toPoint()跨版本的时候要留意。5.3 用 QSettings 记住上次打开的目录每次启动都回到默认目录用起来很烦。QSettings可以持久化窗口状态和最后访问的路径。// 程序退出时保存 void MainWindow::closeEvent(QCloseEvent *event) { QSettings settings(MyCompany, SimpleFileManager); settings.setValue(lastPath, ui-lineEditPath-text()); settings.setValue(geometry, saveGeometry()); QMainWindow::closeEvent(event); } // 程序启动时恢复 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui-setupUi(this); QSettings settings(MyCompany, SimpleFileManager); QString lastPath settings.value(lastPath, QDir::homePath()).toString(); restoreGeometry(settings.value(geometry).toByteArray()); // 用 lastPath 初始化模型根路径 }QSettings在 Windows 上写注册表在 Linux/macOS 上写配置文件跨平台行为一致。参数里的组织名和应用名可以随便填但一旦发布过版本就不要改否则用户之前的配置会丢失。5.4 一个我踩过的坑模型索引失效改造过程中最容易翻车的地方是模型索引的生命周期。QModelIndex是轻量级的临时对象当底层模型的数据发生变化比如目录被删除、文件被重命名时之前保存的QModelIndex可能就失效了。如果你在某个槽函数里缓存了索引过一会儿再去用程序可能直接崩溃。我的习惯是永远不跨事件循环保存QModelIndex需要持久化路径信息就存QString用的时候再通过model-index(path)重新获取。从那以后我每次改文件操作相关的代码都会强制走一遍「删除 → 刷新 → 再操作」的流程确认没有悬空索引才收工。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

运动想象脑电分类实战:CNN局部特征+Transformer全局注意力

运动想象脑电分类实战:CNN局部特征+Transformer全局注意力

简介:运动想象脑电信号分类项目,基于Transformer框架并结合CNN提取局部时间空间特征,是一份完整的Python毕设源码,面向计算机、人工智能及相关专业的学生与从业者,可用于期末课程设计、大作业或毕业设计等场景。项目由…

2026/10/11 13:17:54 阅读更多 →
WSL2系统时间漂移怎么解决?从根因到自动校准完整指南

WSL2系统时间漂移怎么解决?从根因到自动校准完整指南

最近在做一次AI使用验证时,我把环境搭在了Windows上,通过WSL2装了一个Ubuntu系统。任务本身不算复杂,但运行到第二天,我注意到一个特别诡异的细节:Ubuntu里的系统时间比宿主机Windows慢了好几分钟,而且这个…

2026/10/11 13:17:54 阅读更多 →
bloub自定义指南:8种形状×12种颜色×16种表情,打造专属AI机器人头像

bloub自定义指南:8种形状×12种颜色×16种表情,打造专属AI机器人头像

前端图形学 【免费下载链接】bloub SVG recreation of the x.ai bot avatar. One shape morphing through 14 states, measured off the reference video frame by frame. 项目地址: https://gitcode.com/gh_mirrors/bl/bloub 点击查看 免费下载 bloub 是一个纯 SV…

2026/10/11 13:16:53 阅读更多 →

最新新闻

Flink 1.13.1 与 CDH 6.3.2 集成实战:YARN 提交与 Hive 接入指南

Flink 1.13.1 与 CDH 6.3.2 集成实战:YARN 提交与 Hive 接入指南

简介:面向需要在 CDH 6.3.2 集群中部署 Flink 1.13.1 的大数据运维与开发人员,这份安装包提供了完整的 Parcel 分发包与 YARN 集成组件,解决实时计算环境搭建、作业提交发布以及版本兼容与资源配置问题。资源共 5 个文件,包含 Fli…

2026/10/11 14:05:18 阅读更多 →
手语识别系统全栈实战:OpenCV+Python+MySQL图像识别链路

手语识别系统全栈实战:OpenCV+Python+MySQL图像识别链路

简介:面向计算机相关专业毕业生与开发者的手语识别系统完整项目,整合Python、OpenCV、JavaScript与MySQL,旨在通过摄像头实时捕获手势并识别输出文字,提升非手语使用者与听障人士的沟通效率。资源包共85个文件,包含42张…

2026/10/11 14:05:18 阅读更多 →
Oracle ODA一体机:预调优数据库交付引擎解析

Oracle ODA一体机:预调优数据库交付引擎解析

简介:本资源是一份面向数据库工程师、系统架构师及Oracle技术学习者的专业课件,聚焦Oracle Database Appliance(ODA)一体机的演进脉络、核心架构与实战价值。内容系统梳理了从ODA X3-2到X8-2系列的迭代升级路径,深入解…

2026/10/11 14:05:18 阅读更多 →
甘蔗病害图像分类数据集:19000张标注样本的预处理与模型训练实战

甘蔗病害图像分类数据集:19000张标注样本的预处理与模型训练实战

简介:本资源为一份面向计算机视觉学习者的甘蔗植物病害图像分类数据集,适用于图像分类模型训练、算法对比与课程实践等场景,尤其适合正在做农业病害识别或深度学习入门项目的人群。数据集共标注约19,000张图像,涵盖红腐病、锈病、…

2026/10/11 14:05:18 阅读更多 →
行人重识别源码实战:从解压到训练评估全流程

行人重识别源码实战:从解压到训练评估全流程

简介:一份面向本科毕业设计场景的行人重识别(Person Re-ID)Python源码项目,基于深度学习实现完整可运行的跨摄像头目标检索系统,流程覆盖数据加载与管理、ResNet特征提取、损失函数计算、距离度量、训练评估等核心环节…

2026/10/11 14:05:18 阅读更多 →
LSTM多变量预测实战:用Python搭建成绩预测模型

LSTM多变量预测实战:用Python搭建成绩预测模型

简介:面向希望掌握LSTM多变量预测的Python开发者,这份资源以成绩预测等场景为主线,系统覆盖时间序列转监督数据、数据预处理、模型定义与训练、评估优化等关键环节;同时按单变量、多变量和多步预测拆分为多个模块,并配…

2026/10/11 14:04:17 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →