|
17 | 17 |
|
18 | 18 | class PPTToImageSlidesGUI: |
19 | 19 | def __init__(self): |
20 | | - self.root = tk.Tk() |
| 20 | + # 优先尝试用tkinterdnd2增强主窗口 |
| 21 | + self.dnd_enabled = False |
| 22 | + try: |
| 23 | + from tkinterdnd2 import TkinterDnD |
| 24 | + self.root = TkinterDnD.Tk() |
| 25 | + self.dnd_enabled = True |
| 26 | + except ImportError: |
| 27 | + self.root = tk.Tk() |
21 | 28 | self.root.title("PPT转图片幻灯片工具 - 背景版") |
22 | 29 | self.root.geometry("700x700") |
23 | 30 | self.root.resizable(True, True) |
24 | | - |
| 31 | + |
25 | 32 | # 消息队列用于线程间通信 |
26 | 33 | self.message_queue = queue.Queue() |
27 | | - |
| 34 | + |
28 | 35 | # 创建GUI界面 |
29 | 36 | self.create_widgets() |
30 | | - |
| 37 | + |
| 38 | + # 拖拽支持 |
| 39 | + self.add_drag_and_drop_support() |
| 40 | + |
31 | 41 | # 设置关闭事件 |
32 | 42 | self.root.protocol("WM_DELETE_WINDOW", self.on_closing) |
33 | | - |
| 43 | + |
34 | 44 | # 启动消息处理 |
35 | 45 | self.process_queue() |
| 46 | + def add_drag_and_drop_support(self): |
| 47 | + """为主窗口添加文件拖拽支持,仅支持PPT文件""" |
| 48 | + if getattr(self, 'dnd_enabled', False): |
| 49 | + # 用tkinterdnd2增强拖拽体验 |
| 50 | + self.root.drop_target_register('DND_Files') |
| 51 | + self.root.dnd_bind('<<Drop>>', self.on_drop_file) |
| 52 | + else: |
| 53 | + # 降级为普通Tk,提示用户 |
| 54 | + self.log("未检测到tkinterdnd2库,拖拽功能受限。可通过 pip install tkinterdnd2 获得更好体验。") |
| 55 | + # 绑定简单的拖拽事件(大多数Tk无效,仅保留提示) |
| 56 | + pass |
| 57 | + |
| 58 | + def on_drop_file(self, event): |
| 59 | + """拖拽文件到窗口时的处理,支持带空格路径""" |
| 60 | + import re |
| 61 | + data = event.data.strip() |
| 62 | + # 用正则提取所有大括号包裹的路径,否则按空格分割 |
| 63 | + paths = re.findall(r'\{([^}]*)\}', data) |
| 64 | + if not paths: |
| 65 | + # 没有大括号,直接按空格分割 |
| 66 | + paths = data.split() |
| 67 | + if not paths: |
| 68 | + self.log("未检测到有效的文件路径") |
| 69 | + return |
| 70 | + file_path = paths[0] |
| 71 | + # 检查扩展名 |
| 72 | + if file_path.lower().endswith(('.ppt', '.pptx')): |
| 73 | + self.selected_file = file_path |
| 74 | + display_name = os.path.basename(file_path) |
| 75 | + if len(display_name) > 50: |
| 76 | + display_name = display_name[:47] + "..." |
| 77 | + self.file_var.set(display_name) |
| 78 | + self.log(f"已拖入文件: {file_path}") |
| 79 | + self.convert_btn.config(state=tk.NORMAL) |
| 80 | + else: |
| 81 | + self.log(f"拖入的文件不是PPT: {file_path}") |
| 82 | + messagebox.showwarning("文件类型不支持", "请拖入PPT或PPTX文件!") |
36 | 83 |
|
37 | 84 | def create_widgets(self): |
38 | 85 | """创建GUI组件""" |
@@ -243,13 +290,22 @@ def start_conversion(self): |
243 | 290 | conversion_thread.start() |
244 | 291 |
|
245 | 292 | def convert_in_thread(self, input_ppt, output_ppt): |
246 | | - """在线程中执行转换""" |
| 293 | + """在线程中执行转换,需初始化COM""" |
247 | 294 | try: |
248 | | - success = self.convert_ppt_to_image_slides(input_ppt, output_ppt) |
249 | | - self.message_queue.put(('conversion_complete', (success, output_ppt))) |
250 | | - except Exception as e: |
251 | | - self.log(f"转换过程发生异常: {e}") |
252 | | - self.message_queue.put(('conversion_complete', (False, output_ppt))) |
| 295 | + import pythoncom |
| 296 | + pythoncom.CoInitialize() |
| 297 | + try: |
| 298 | + success = self.convert_ppt_to_image_slides(input_ppt, output_ppt) |
| 299 | + self.message_queue.put(('conversion_complete', (success, output_ppt))) |
| 300 | + except Exception as e: |
| 301 | + self.log(f"转换过程发生异常: {e}") |
| 302 | + self.message_queue.put(('conversion_complete', (False, output_ppt))) |
| 303 | + finally: |
| 304 | + try: |
| 305 | + import pythoncom |
| 306 | + pythoncom.CoUninitialize() |
| 307 | + except: |
| 308 | + pass |
253 | 309 |
|
254 | 310 | def on_conversion_complete(self, success, output_file): |
255 | 311 | """转换完成回调""" |
|
0 commit comments