上学期教Python,其中一部分内容受限于课时,没有完全使用。
学习GUI编程,最好的方式就是看一个完整的、有实际功能的项目。
今天介绍一个小工具——FolderLens,它是一个基于PySide6开发的文件浏览器,代码量适中,适合作为学习Qt开发的参考项目。
项目简介
FolderLens是一个桌面文件管理工具,提供了文件夹浏览、搜索、文件操作等基础功能。整个项目约900行代码,结构清晰,没有过度设计,适合初学者阅读和学习。
主要功能:
- 树形结构浏览文件夹
- 异步计算文件夹大小
- 文件搜索与过滤
- 右键菜单操作(复制、粘贴、删除、重命名等)
- 多语言支持(中英文切换)
- 键盘快捷键





技术要点
1. 信号与槽机制
Qt的核心是信号与槽。在这个项目中,有不少典型的应用场景:
# 按钮点击连接
self.open_path_button.clicked.connect(self._open_path)
# 树节点展开时加载子目录
self.itemExpanded.connect(self._on_item_expanded)
# 自定义信号
class SizeCalculatorSignals(QObject):
size_computed = Signal(str, object)
信号与槽是Qt实现组件通信的基础,理解它对后续学习很重要。
2. 多线程处理
计算文件夹大小是个耗时操作,如果在主线程执行,界面会卡顿。项目使用QThreadPool和QRunnable来处理:
class SizeCalculator(QRunnable):
def __init__(self, path: str):
super().__init__()
self.path = path
self.signals = SizeCalculatorSignals()
def run(self):
total_size = self._calculate_folder_size(self.path)
self.signals.size_computed.emit(self.path, total_size)
主线程把任务丢给线程池,计算完成后通过信号通知主线程更新界面。这是Qt中处理耗时任务的标准做法。
3. 国际化支持
项目使用了Qt的翻译机制:
# 所有界面文字都用translate包裹
QCoreApplication.translate("FileTreeWidget", "Name")
QCoreApplication.translate("FolderLens", "Open Path")
配合.ts翻译文件和.qm编译后的二进制文件,实现了中英文切换。虽然对于小工具可能没必要,但作为学习材料,展示了完整的国际化流程。
4. 右键菜单与快捷键
文件管理器的右键菜单是个常见需求:
def _show_context_menu(self, position):
menu = QMenu(self)
open_action = menu.addAction(
QCoreApplication.translate("FileTreeWidget", "Open"))
# ... 添加更多菜单项
action = menu.exec(self.viewport().mapToGlobal(position))
if action == open_action:
self._open_selected()
快捷键的处理也很直接:
shortcuts = {
"Ctrl+C": self._copy_items,
"Ctrl+X": self._cut_items,
"Ctrl+V": self._paste_items,
"Delete": self._delete_selected,
}
for key, action in shortcuts.items():
shortcut = QShortcut(QKeySequence(key), self)
shortcut.activated.connect(action)
5. 文件操作的错误处理
文件操作容易出错(权限不足、文件被占用等),项目展示了基本的异常处理模式:
try:
os.remove(file_path)
except Exception as e:
QMessageBox.warning(
self,
QCoreApplication.translate("FileTreeWidget", "Error"),
str(e)
)
用QMessageBox给用户反馈,比静默失败更友好。
代码结构
项目的代码组织比较简单:
folderlens/
├── src/folderlens/
│ ├── __init__.py # 包入口,导出主要类
│ ├── __main__.py # 命令行入口
│ ├── app.py # 主程序(所有代码在一个文件)
│ ├── *.ts # 翻译源文件
│ └── *.qm # 编译后的翻译文件
└── tests/
└── test_app.py # 测试(目前只有一个示例测试)
对于这个规模的项目,把代码放在一个文件里是可以接受的。如果要扩展,可以考虑拆分:
widgets/- 自定义控件utils/- 工具函数workers/- 后台任务
项目特点
类型注解:代码使用了Python 3.10+的类型提示,阅读起来更清晰:
def _human_readable_size(self, size: int | float, decimal_places: int = 2) -> str:
def populate(self, path: str | None = None, parent_item: QTreeWidgetItem | None = None):
自定义排序:FileTreeWidgetItem重写了__lt__方法,让文件大小列能按数值而非字符串排序:
def __lt__(self, other):
if column == 3: # 大小列
my_size = self.data(3, Qt.UserRole) or 0
other_size = other.data(3, Qt.UserRole) or 0
return my_size < other_size
return self.text(column).lower() < other.text(column).lower()
懒加载:文件夹展开时才加载子目录,避免一次性扫描整个目录树:
def _on_item_expanded(self, item):
if item.childCount() == 0:
path = item.data(self.COLUMN_NAME, Qt.UserRole)
self.populate(path, parent_item=item)
如何运行
# 安装
pip install -e ".[dev]"
# 运行
folderlens
# 或者
python -m folderlens
适合学习的内容
- Qt基础控件使用:QTreeWidget、QMainWindow、QMenu、QDialog等
- 信号与槽机制:内置信号、自定义信号
- 多线程编程:QThreadPool、QRunnable
- 国际化:翻译文件的使用
- 文件操作:shutil、os模块的常见用法
可以改进的地方
作为学习项目,也有一些可以思考和改进的点:
- 测试覆盖率低:目前只有一个示例测试,可以增加更多单元测试
- 配置持久化:记住上次打开的目录、窗口大小等
- 更多视图模式:图标视图、列表视图
- 拖拽支持:虽然设置了
setDragEnabled,但没有完整实现拖拽操作
总结
FolderLens是一个适中的PySide6学习项目——功能完整但不臃肿,代码规范但不教条。如果你正在学习Qt开发,可以克隆下来读一读代码,尝试添加新功能,或者修复一些"不经意留下"的小问题。
项目地址:https://github.com/cycleuser/FolderLens
有问题欢迎提Issue讨论。
预览时标签不可点
Close
更多
Name cleared
微信扫一扫赞赏作者
Like the AuthorOther Amount
赞赏后展示我的头像
作品
暂无作品
Like the Author
Other Amount
¥
最低赞赏 ¥0
OK
Back
Other Amount
更多
赞赏金额
¥
最低赞赏 ¥0
1
2
3
4
5
6
7
8
9
0
.
虚拟化,操作系统,以及一些小工具 · 目录
虚拟化,操作系统,以及一些小工具
上一篇Xie(写):把 Markdown 转成微信公众号格式网页的小工具下一篇Chou(瞅)-PDF论文重命名工具升级了!这次专门优化了中文论文支持
Close
更多
搜索「」网络结果
Close
调整当前正文文字大小
更多
100%