[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
import os
import threading
from queue import Queue
try:
from PyPDF2 import PdfMerger
except ModuleNotFoundError:
import sys
sys.exit("Error: PyPDF2 模块未安装,请运行 'pip install PyPDF2' 进行安装")
class PDFMergerApp:
def __init__(self):
self.window = tk.Tk()
self.window.title('📄 PDF合并打印软件')
self.window.geometry('700x450')
self.window.configure(bg='#F8FAFC')
# 创建现代风格按钮
self.button_style = {
'background': '#4F46E5',
'foreground': 'white',
'borderwidth': 0,
'relief': 'flat',
'font': ('微软雅黑', 12, 'bold'),
'padx': 30,
'pady': 15
}
# 主容器框架,添加圆角和阴影效果
main_frame = tk.Frame(self.window, bg='#FFFFFF')
main_frame.grid_columnconfigure(0, weight=1)
main_frame.grid_rowconfigure(1, weight=1)
main_frame.pack(expand=True, fill='both', padx=35, pady=30)
# 标题标签
title_label = tk.Label(
main_frame,
text='PDF文件合并工具',
font=('微软雅黑', 20, 'bold'),
fg='#1E293B',
bg='#FFFFFF',
pady=20
)
title_label.grid(row=0, column=0, sticky='ew')
# 文件选择按钮容器
button_frame = tk.Frame(main_frame, bg='#FFFFFF', padx=20)
button_frame.grid(row=1, column=0, sticky='ew')
button_frame.grid_columnconfigure(0, weight=1)
# 文件选择按钮
select_button = tk.Button(
button_frame,
text='🖇️ 选择并合并PDF文件',
command=self.select_and_merge_pdfs,
cursor='hand2',
**self.button_style
)
select_button.grid(row=0, column=0, pady=(25,35), sticky='ew')
# 状态标签
self.status_label = tk.Label(main_frame,
text='准备就绪',
font=('微软雅黑', 11),
fg='#64748B',
bg='#FFFFFF',
padx=15,
pady=12)
self.status_label.grid(row=2, column=0, pady=(5,15), sticky='ew')
# 配置悬停效果
select_button.bind('<Enter>', lambda e: select_button.config(background='#4338CA'))
select_button.bind('<Leave>', lambda e: select_button.config(background='#4F46E5'))
# 设置窗口图标
try:
self.window.iconbitmap('pdf_icon.ico')
except:
pass
# 用于线程间通信
self.queue = Queue()
def update_progress(self):
try:
while not self.queue.empty():
msg = self.queue.get_nowait()
if msg.startswith('status:'):
self.status_label['text'] = msg.split(':')[1]
elif msg.startswith('error:'):
messagebox.showerror('错误', f'处理PDF时出错:{msg.split(":", 1)[1]}')
elif msg == 'done':
return
except Queue.Empty:
pass
self.window.after(50, self.update_progress)
def merge_pdfs_thread(self, files):
try:
merger = PdfMerger(strict=False)
total_files = len(files)
for i, pdf_file in enumerate(files, 1):
with open(pdf_file, 'rb') as pdf:
merger.append(fileobj=pdf, import_outline=False)
self.queue.put(f'status:正在处理: {os.path.basename(pdf_file)}')
output_path = os.path.join(os.path.dirname(files[0]), 'merged_output.pdf')
self.queue.put('status:正在保存文件...')
with open(output_path, 'wb') as output:
merger.write(fileobj=output)
merger.close()
self.queue.put('status:完成!')
os.startfile(output_path)
except Exception as e:
self.queue.put(f'error:{str(e)}')
finally:
self.queue.put('done')
def select_and_merge_pdfs(self):
# 打开文件选择对话框
files = filedialog.askopenfilenames(
title='选择PDF文件',
filetypes=[('PDF files', '*.pdf')]
)
if files:
# 重置状态
self.status_label['text'] = '准备处理...'
# 启动处理线程
thread = threading.Thread(target=self.merge_pdfs_thread, args=(files,))
thread.daemon = True
thread.start()
# 启动进度更新
self.window.after(100, self.update_progress)
def run(self):
self.window.mainloop()
if __name__ == '__main__':
app = PDFMergerApp()
app.run()