如何在KivyMD中实现文件选择弹窗并存储文件路径?(附PDF压缩GUI应用示例代码)
实现KivyMD PDF选择与压缩功能的完整方案
我会帮你实现文件选择功能,同时修正现有代码里的一些小问题,让整个应用更规范易用。下面是完整的可运行代码,以及详细的修改说明:
完整代码
from kivy.config import Config from PDFNetPython.PDFNetPython import PDFDoc, Optimizer, SDFDoc, PDFNet from kivymd.app import MDApp from kivy.lang import Builder from kivy.core.window import Window import os from kivymd.uix.filemanager import MDFileManager from kivymd.toast import toast Config.set('graphics', 'resizable', False) Window.size = (270, 300) # UI布局定义 s = """ MDScreen: md_bg_color : [250/255,34/255,83/255,1] """ c_file = """ MDRaisedButton: text: "Choose PDF" pos_hint : {"center_x": .5, "center_y": .6} size_hint : None,None on_press : app.choose_file() md_bg_color : 0,0,0,1 width : 250 font_size : 20 """ comp = """ MDRaisedButton: text : "Compress" pos_hint : {"center_x": .5, "center_y": .4} size_hint : None,None on_press : app.compress() md_bg_color : 0,0,0,1 disabled : True width : 300 font_size : 24.5 """ class mainApp(MDApp): def __init__(self, **kwargs): super().__init__(**kwargs) # 初始化文件管理器,只允许选择PDF文件 self.file_manager = MDFileManager( exit_manager=self.exit_manager, select_path=self.select_path, ext=[".pdf"], ) self.selected_pdf_path = None # 存储选中的PDF路径 self.compress_btn = None # 压缩按钮实例引用 @staticmethod def get_size_format(n, b, factor=1024, suffix="B"): for unit in ["", "K", "M", "G", "T", "P", "E", "Z"]: if b < factor: return f"{b:.2f}{unit}{suffix}" b /= factor return f"{b:.2f}Y{suffix}" def compress(self): if not self.selected_pdf_path: toast("请先选择PDF文件") return input_path = self.selected_pdf_path output_path = input_path[:input_path.index(".")] + "_compressed.pdf" initial_size = os.path.getsize(input_path) try: PDFNet.Initialize() doc = PDFDoc(input_path) doc.InitSecurityHandler() Optimize.Optimize(doc) doc.Save(output_path, SDFDoc.e_linearized) doc.Close() # 显示压缩结果提示 compressed_size = os.path.getsize(output_path) toast(f"压缩完成!\n原大小: {self.get_size_format(0, initial_size)}\n压缩后: {self.get_size_format(0, compressed_size)}") self.compress_btn.disabled = True except Exception as e: doc.Close() toast(f"压缩失败: {str(e)}") def choose_file(self): # 打开文件管理器,起始路径为用户家目录 self.file_manager.show(os.path.expanduser("~")) def select_path(self, path): # 处理选中的文件 if path and path.endswith(".pdf"): self.selected_pdf_path = path self.compress_btn.disabled = False toast(f"已选择文件: {os.path.basename(path)}") else: toast("请选择有效的PDF文件") self.exit_manager() def exit_manager(self, *args): # 关闭文件管理器窗口 self.file_manager.close() def build(self): screen = Builder.load_string(s) choose_btn = Builder.load_string(c_file) self.compress_btn = Builder.load_string(comp) screen.add_widget(self.compress_btn) screen.add_widget(choose_btn) return screen if __name__ == "__main__": mainApp().run()
关键修改与功能说明
文件选择功能实现
- 使用KivyMD原生的
MDFileManager组件弹出文件选择窗口,设置ext=[".pdf"]过滤只显示PDF文件,避免用户选错格式。 choose_file方法触发打开文件管理器,select_path方法处理选中的文件路径,验证后保存到实例属性self.selected_pdf_path,同时启用压缩按钮。
- 使用KivyMD原生的
代码规范修正
- 把原来的全局变量
com替换为实例属性self.compress_btn,符合面向对象编程规范,避免全局变量冲突。 - 修正了类方法的参数问题:给
choose_file、compress添加了self参数,把get_size_format标记为静态方法(因为它不需要访问实例属性)。
- 把原来的全局变量
用户体验优化
- 添加了
toast提示,用户选择文件、压缩成功/失败时都会弹出友好的提示信息。 - 压缩完成后自动禁用压缩按钮,防止重复操作;如果用户未选择文件就点击压缩,也会弹出提示。
- 添加了
压缩逻辑整合
- 压缩方法直接使用
self.selected_pdf_path作为输入路径,完美对接你已有的压缩逻辑,无需额外修改核心压缩代码。
- 压缩方法直接使用
内容的提问来源于stack exchange,提问作者Colton Walker
相关产品推荐
相关产品推荐

