-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgui.py
More file actions
160 lines (132 loc) · 6.7 KB
/
gui.py
File metadata and controls
160 lines (132 loc) · 6.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import tkinter as tk
from tkinter import filedialog, messagebox, Canvas, Frame
from pdf2image import convert_from_path
from PIL import ImageTk
# Import the splitting logic from our separate module.
from pdf_splitter_logic import split_pdf_file
class PDFSplitterApp:
def __init__(self, root):
self.root = root
self.root.title("PDF Splitter with Preview")
self.root.geometry("1000x700")
self.pdf_path_var = tk.StringVar()
self.split_points = [] # List of page numbers indicating the start of a new section.
self.thumbnails = [] # Store thumbnail images (Tkinter PhotoImage)
self.images = [] # Store PIL image references to avoid garbage collection
self.columns = 4 # Number of columns in grid
self.setup_ui()
def setup_ui(self):
"""Create the main GUI elements."""
tk.Label(self.root, text="Select PDF File:").pack(pady=5)
tk.Entry(self.root, textvariable=self.pdf_path_var, width=60, state="readonly").pack()
tk.Button(self.root, text="Browse", command=self.select_pdf).pack(pady=5)
# Scrollable frame for thumbnails
self.preview_frame = Frame(self.root)
self.preview_frame.pack(pady=10, fill=tk.BOTH, expand=True)
self.canvas = Canvas(self.preview_frame)
self.scroll_y = tk.Scrollbar(self.preview_frame, orient="vertical", command=self.canvas.yview)
self.scroll_y.pack(side="right", fill="y")
self.scrollable_frame = Frame(self.canvas)
self.scrollable_frame.bind(
"<Configure>",
lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all"))
)
self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
self.canvas.configure(yscrollcommand=self.scroll_y.set)
self.canvas.pack(side="left", fill=tk.BOTH, expand=True)
# Enable mouse wheel scrolling
self.canvas.bind_all("<MouseWheel>", self.on_mouse_wheel) # Windows
self.canvas.bind_all("<Button-4>", self.on_mouse_wheel) # macOS/Linux scroll up
self.canvas.bind_all("<Button-5>", self.on_mouse_wheel) # macOS/Linux scroll down
tk.Button(self.root, text="Split PDF", command=self.split_pdf).pack(pady=10)
def on_mouse_wheel(self, event):
"""Enable scrolling with the mouse wheel."""
if event.num == 5 or event.delta < 0:
self.canvas.yview_scroll(1, "units")
elif event.num == 4 or event.delta > 0:
self.canvas.yview_scroll(-1, "units")
def select_pdf(self):
"""Open a file dialog to select a PDF file."""
file_path = filedialog.askopenfilename(filetypes=[("PDF Files", "*.pdf")])
if file_path:
self.pdf_path_var.set(file_path)
self.load_preview()
def load_preview(self):
"""Generate and display page thumbnails with clickable split markers."""
pdf_path = self.pdf_path_var.get()
if not pdf_path:
return
# Clear previous content.
for widget in self.scrollable_frame.winfo_children():
widget.destroy()
self.split_points.clear()
self.thumbnails.clear()
self.images.clear()
# Convert PDF pages to thumbnail images.
images = convert_from_path(pdf_path, size=(180, 240))
num_pages = len(images)
rows = (num_pages // self.columns) + (1 if num_pages % self.columns else 0)
for row in range(rows):
row_frame = Frame(self.scrollable_frame)
row_frame.pack(fill="x", pady=5)
for col in range(self.columns):
page_idx = row * self.columns + col
if page_idx >= num_pages:
break
img = images[page_idx]
thumbnail = ImageTk.PhotoImage(img)
self.thumbnails.append(thumbnail)
self.images.append(img) # Avoid garbage collection.
# Create a container for each page preview.
page_container = Frame(row_frame, borderwidth=2, relief="solid")
page_container.pack(side="left", padx=5)
img_label = tk.Label(page_container, image=thumbnail)
img_label.pack()
page_num_label = tk.Label(page_container, text=f"Page {page_idx + 1}")
page_num_label.pack()
# Add a vertical split marker after every column except the last in the row.
if col < self.columns - 1 and page_idx + 1 < num_pages:
# The marker indicates that the next section starts at page (page_idx + 2)
separator = Canvas(row_frame, width=5, height=250, bg="gray")
separator.pack(side="left", padx=2)
separator.bind("<Button-1>", lambda e, page=page_idx + 2: self.toggle_split_point(page, e))
# Add a vertical split marker at the end of each row if it is not the last page.
last_page_in_row = row * self.columns + (self.columns - 1)
if last_page_in_row < num_pages - 1:
end_separator = Canvas(row_frame, width=5, height=250, bg="gray")
end_separator.pack(side="left", padx=2)
end_separator.bind("<Button-1>", lambda e, page=last_page_in_row + 2: self.toggle_split_point(page, e))
# Update the canvas scroll region.
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def toggle_split_point(self, page, event):
"""
Toggle the split point when a marker is clicked.
The parameter 'page' indicates the first page of the new part.
For example, clicking a marker that gives page 4 will result in:
- Part 1: pages 1–3
- Part 2: starting at page 4
"""
if page in self.split_points:
self.split_points.remove(page)
event.widget.config(bg="gray")
else:
self.split_points.append(page)
event.widget.config(bg="red")
self.split_points.sort()
def split_pdf(self):
"""Call the splitting logic to split the PDF file."""
pdf_path = self.pdf_path_var.get()
if not pdf_path or not self.split_points:
messagebox.showerror("Error", "Please select a PDF file and at least one split point.")
return
try:
# Call the splitting logic (from pdf_splitter_logic.py)
output_dir = split_pdf_file(pdf_path, self.split_points)
messagebox.showinfo("Success", f"PDF split successfully!\nFiles saved in: {output_dir}")
except Exception as e:
messagebox.showerror("Error", str(e))
# Run the app.
if __name__ == "__main__":
root = tk.Tk()
app = PDFSplitterApp(root)
root.mainloop()