win10程序(十四)pdf转docx简易版

'''

这是一个使用Python和Tkinter开发的PDF转DOCX转换工具,具有美观的糖果色界面和批量转换功能。

功能特点

  • 批量选择和转换PDF文件

  • 糖果色主题的友好界面

  • 实时转换进度显示

  • 详细的转换日志记录

  • 简单易用的操作方式

'''

-*- coding: utf-8 -*-

import tkinter as tk

from tkinter import filedialog, messagebox, ttk

import os

import threading

import time

import sys

检查依赖项

try:

from pdf2docx import Converter

DEPENDENCY_AVAILABLE = True

except ImportError:

DEPENDENCY_AVAILABLE = False

print("警告: 未找到pdf2docx模块,请运行 'pip install pdf2docx' 来安装")

class PDFtoDOCXConverter:

def init(self, root):

self.root = root

self.root.title("PDF转DOCX转换器")

self.root.geometry("1000x600") # 调整窗口大小以适应内容

self.root.resizable(True, True) # 允许调整窗口大小

设置糖果色主题

self.colors = {

'primary': '#FF6B6B', # 珊瑚粉

'secondary': '#4ECDC4', # 薄荷绿

'accent1': '#FFD166', # 芒果黄

'accent2': '#06D6A0', # 青柠绿

'accent3': '#118AB2', # 天空蓝

'background': '#F7F9FC', # 浅灰白

'text': '#2D3142', # 深灰蓝

'light_text': '#6C757D' # 浅灰色

}

设置背景颜色

self.root.configure(bg=self.colors['background'])

存储选择的文件

self.selected_files = []

创建界面

self.create_widgets()

def create_widgets(self):

创建主框架

main_frame = tk.Frame(self.root, bg=self.colors['background'])

main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

创建左侧控制面板

control_frame = tk.Frame(main_frame, bg=self.colors['background'], width=300)

control_frame.pack(side=tk.LEFT, fill=tk.Y, padx=10)

添加按钮

self.create_buttons(control_frame)

创建右侧文件列表和日志区域

content_frame = tk.Frame(main_frame, bg=self.colors['background'])

content_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=10)

文件列表区域

files_frame = tk.LabelFrame(content_frame, text="待转换文件",

font=("微软雅黑", 12),

bg=self.colors['background'],

fg=self.colors['text'])

files_frame.pack(fill=tk.BOTH, expand=True, pady=10)

文件列表

self.create_file_list(files_frame)

日志区域

log_frame = tk.LabelFrame(content_frame, text="转换日志",

font=("微软雅黑", 12),

bg=self.colors['background'],

fg=self.colors['text'])

log_frame.pack(fill=tk.BOTH, expand=True, pady=10)

日志文本框

self.create_log_text(log_frame)

def create_buttons(self, parent):

选择文件按钮

select_btn = tk.Button(parent, text="选择PDF文件",

font=("微软雅黑", 14),

bg=self.colors['accent1'],

fg=self.colors['text'],

command=self.select_files,

relief=tk.RAISED,

bd=0,

height=2,

width=20)

select_btn.pack(pady=15)

select_btn.bind("<Enter>", lambda e: select_btn.config(bg="#FFE066"))

select_btn.bind("<Leave>", lambda e: select_btn.config(bg=self.colors['accent1']))

转换按钮

convert_btn = tk.Button(parent, text="开始转换",

font=("微软雅黑", 14),

bg=self.colors['accent2'],

fg="white",

command=self.start_conversion,

relief=tk.RAISED,

bd=0,

height=2,

width=20)

convert_btn.pack(pady=15)

convert_btn.bind("<Enter>", lambda e: convert_btn.config(bg="#06E6A0"))

convert_btn.bind("<Leave>", lambda e: convert_btn.config(bg=self.colors['accent2']))

清空列表按钮

clear_btn = tk.Button(parent, text="清空列表",

font=("微软雅黑", 14),

bg=self.colors['accent3'],

fg="white",

command=self.clear_files,

relief=tk.RAISED,

bd=0,

height=2,

width=20)

clear_btn.pack(pady=15)

clear_btn.bind("<Enter>", lambda e: clear_btn.config(bg="#119AB2"))

clear_btn.bind("<Leave>", lambda e: clear_btn.config(bg=self.colors['accent3']))

def create_file_list(self, parent):

创建滚动条

scrollbar = tk.Scrollbar(parent)

scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

创建列表框

self.file_listbox = tk.Listbox(parent,

font=("微软雅黑", 10),

bg="white",

fg=self.colors['text'],

selectbackground=self.colors['accent1'],

selectforeground=self.colors['text'],

width=70,

height=10,

yscrollcommand=scrollbar.set)

self.file_listbox.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

scrollbar.config(command=self.file_listbox.yview)

def create_log_text(self, parent):

创建滚动条

scrollbar = tk.Scrollbar(parent)

scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

创建文本框

self.log_text = tk.Text(parent,

font=("微软雅黑", 10),

bg="white",

fg=self.colors['text'],

width=70,

height=8,

yscrollcommand=scrollbar.set,

state=tk.DISABLED)

self.log_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)

scrollbar.config(command=self.log_text.yview)

def select_files(self):

files = filedialog.askopenfilenames(

title="选择PDF文件",

filetypes=[("PDF文件", "*.pdf"), ("所有文件", "*.*")]

)

if files:

for file in files:

if file not in self.selected_files:

self.selected_files.append(file)

self.file_listbox.insert(tk.END, os.path.basename(file))

self.log("已添加 {} 个文件".format(len(files)))

def clear_files(self):

if self.selected_files:

self.selected_files.clear()

self.file_listbox.delete(0, tk.END)

self.log("文件列表已清空")

else:

messagebox.showinfo("提示", "文件列表已为空")

def start_conversion(self):

if not self.selected_files:

messagebox.showwarning("警告", "请先选择PDF文件")

return

选择输出目录

output_dir = filedialog.askdirectory(title="选择输出目录")

if not output_dir:

return

禁用转换按钮防止重复点击

for widget in self.root.winfo_children():

if isinstance(widget, tk.Frame) and widget.winfo_children():

for child in widget.winfo_children():

if isinstance(child, tk.Frame) and child.winfo_children():

for btn in child.winfo_children():

if isinstance(btn, tk.Button) and btn["text"] == "开始转换":

btn.config(state=tk.DISABLED)

在新线程中开始转换

self.total_files = len(self.selected_files)

self.current_file = 0

thread = threading.Thread(target=self.convert_files, args=(output_dir,))

thread.daemon = True

thread.start()

def convert_files(self, output_dir):

self.log("开始转换文件...")

确保输出目录存在

if not os.path.exists(output_dir):

try:

os.makedirs(output_dir)

self.log(f"已创建输出目录: {output_dir}")

except Exception as e:

self.log(f"创建输出目录失败: {str(e)}")

在主线程中显示错误消息

self.root.after(0, lambda: messagebox.showerror("错误", f"创建输出目录失败: {str(e)}"))

重新启用转换按钮

self.root.after(0, self._enable_convert_button)

return

success_count = 0

fail_count = 0

for i, pdf_path in enumerate(self.selected_files):

self.current_file = i + 1

filename = os.path.basename(pdf_path)

docx_filename = os.path.splitext(filename)[0] + ".docx"

docx_path = os.path.join(output_dir, docx_filename)

try:

self.log(f"转换中: {filename}")

检查文件是否存在且可读

if not os.path.exists(pdf_path):

raise FileNotFoundError(f"文件不存在: {pdf_path}")

创建转换器并转换

cv = Converter(pdf_path)

cv.convert(docx_path, start=0, end=None)

cv.close()

self.log(f"转换完成: {docx_filename}")

success_count += 1

except Exception as e:

error_msg = f"转换失败: {filename} - {str(e)}"

self.log(error_msg)

fail_count += 1

finally:

仅记录当前进度到日志

self.log(f"进度: {self.current_file}/{self.total_files}")

转换完成

summary = f"转换完成!成功: {success_count}, 失败: {fail_count}"

self.log(summary)

重新启用转换按钮

self.root.after(0, self._enable_convert_button)

在主线程中显示完成消息

self.root.after(0, lambda: messagebox.showinfo("完成", summary))

def _enable_convert_button(self):

"""重新启用转换按钮的辅助方法"""

for widget in self.root.winfo_children():

if isinstance(widget, tk.Frame) and widget.winfo_children():

for child in widget.winfo_children():

if isinstance(child, tk.Frame) and child.winfo_children():

for btn in child.winfo_children():

if isinstance(btn, tk.Button) and btn["text"] == "开始转换":

btn.config(state=tk.NORMAL)

break

def log(self, message):

timestamp = time.strftime("%H:%M:%S")

log_message = f"[{timestamp}] {message}\n"

self.log_text.config(state=tk.NORMAL)

self.log_text.insert(tk.END, log_message)

self.log_text.see(tk.END) # 自动滚动到底部

self.log_text.config(state=tk.DISABLED)

def check_dependencies():

"""检查程序所需的依赖项"""

if not DEPENDENCY_AVAILABLE:

root = tk.Tk()

root.withdraw() # 隐藏主窗口

messagebox.showerror(

"缺少依赖项",

"未找到pdf2docx模块!\n\n请按照以下步骤安装依赖:\n1. 打开命令提示符\n2. 运行: pip install pdf2docx\n3. 然后重新启动程序"

)

root.destroy()

return False

return True

if name == "main":

调试输出

print("程序启动中...")

先检查依赖项

if check_dependencies():

try:

print("依赖项检查通过,创建窗口...")

root = tk.Tk()

print("窗口创建成功,初始化应用...")

app = PDFtoDOCXConverter(root)

print("应用初始化完成,启动主循环...")

root.mainloop()

except Exception as e:

print(f"程序运行出错: {str(e)}")

import traceback

traceback.print_exc()

创建一个简单的错误提示窗口

error_root = tk.Tk()

error_root.title("错误")

error_root.geometry("400x200")

error_label = tk.Label(

error_root,

text=f"程序运行出错:\n{str(e)}",

font=("微软雅黑", 10),

justify=tk.LEFT,

wraplength=380

)

error_label.pack(pady=20)

ok_btn = tk.Button(

error_root,

text="确定",

command=error_root.destroy,

width=10

)

ok_btn.pack(pady=10)

error_root.mainloop()

相关推荐
CodeCraft Studio3 小时前
PDF处理控件Aspose.PDF教程:在Python中向PDF文档添加页面
开发语言·python·pdf
测试老哥3 小时前
Jmeter吞吐量控制器详解
自动化测试·软件测试·python·测试工具·jmeter·测试用例·压力测试
吗喽1号3 小时前
python-xmind转Excel
python·测试工具
令狐掌门4 小时前
python *和**做参数的用法
python·python可变参数
ftpeak4 小时前
《Rust+Slint:跨平台GUI应用》第五章 基础元素
开发语言·ui·rust·slint
寻找华年的锦瑟4 小时前
Qt Quick Application&&Qt Quick Application (compat)
开发语言·qt
国服第二切图仔4 小时前
Rust开发实战之WebSocket通信实现(tokio-tungstenite)
开发语言·websocket·rust
百锦再4 小时前
第5章 所有权系统
运维·git·python·eclipse·go·github·负载均衡
echoyu.4 小时前
java源代码、字节码、jvm、jit、aot的关系
java·开发语言·jvm·八股