DEV Community

Mate Technologies
Mate Technologies

Posted on

Build a PDF Combiner GUI App in Python (Tkinter) — Step-by-Step Beginner Guide

In this tutorial, we will build PDFMate+, a full-featured PDF Combiner & Toolkit using Python and Tkinter.

By the end, you'll learn how to:

Merge PDFs
Convert images to PDF
Add drag & drop support
Create a page editor
Add progress bar & threading
Build a professional desktop UI

👉 Full Source Code:
https://github.com/rogers-cyber/PDFMatePlus

Step 1 — Install Dependencies

First install required packages:

pip install PyPDF2 pillow img2pdf tkinterdnd2 pypdf
Enter fullscreen mode Exit fullscreen mode

Optional (for compression):

Install Ghostscript
https://ghostscript.com

Step 2 — Create Basic Tkinter Window

Start with a simple GUI window.

import tkinter as tk

root = tk.Tk()
root.title("PDFMate+")
root.geometry("900x600")

root.mainloop()
Enter fullscreen mode Exit fullscreen mode

This creates the main application window.

Step 3 — Add Required Imports

Now we import all libraries needed for PDF processing and GUI.

import os
import threading
import tkinter as tk
from tkinter import ttk, filedialog, messagebox

from PIL import Image
from PyPDF2 import PdfWriter, PdfReader
Enter fullscreen mode Exit fullscreen mode

These libraries help us:

Tkinter → UI
PIL → image conversion
PyPDF2 → merge PDFs
threading → background processing
Step 4 — Create Main App Class

We wrap everything in a class.

class PDFMateApp:
    def __init__(self, root):
        self.root = root
        self.root.title("PDFMate+")

        self.items = []

        self.build_ui()
Enter fullscreen mode Exit fullscreen mode

This keeps code organized.

Step 5 — Build UI Layout

Now we create buttons and listbox.

def build_ui(self):
    frame = tk.Frame(self.root)
    frame.pack(fill="both", expand=True)

    self.listbox = tk.Listbox(frame)
    self.listbox.pack(fill="both", expand=True)

    btn = tk.Button(self.root, text="Add Files", command=self.add_files)
    btn.pack()
Enter fullscreen mode Exit fullscreen mode

This gives us:

File list
Add button
Step 6 — Add File Selection

Now we allow users to select PDFs.

def add_files(self):
    files = filedialog.askopenfilenames(
        filetypes=[("PDF Files", "*.pdf")]
    )

    for file in files:
        self.items.append(file)
        self.listbox.insert(tk.END, file)
Enter fullscreen mode Exit fullscreen mode

Users can now add multiple files.

Step 7 — Merge PDFs

This is the core feature.

def merge_pdfs(self):
    writer = PdfWriter()

    for file in self.items:
        reader = PdfReader(file)
        for page in reader.pages:
            writer.add_page(page)

    output = filedialog.asksaveasfilename(
        defaultextension=".pdf"
    )

    with open(output, "wb") as f:
        writer.write(f)
Enter fullscreen mode Exit fullscreen mode

This merges all selected PDFs into one.

Step 8 — Add Merge Button

Add merge button to UI.

merge_btn = tk.Button(
    self.root,
    text="Merge PDFs",
    command=self.merge_pdfs
)
merge_btn.pack()
Enter fullscreen mode Exit fullscreen mode

Step 9 — Add Image to PDF Support

Convert images before merging.

from PIL import Image

def image_to_pdf(self, image_path):
    img = Image.open(image_path).convert("RGB")
    temp = image_path + ".pdf"
    img.save(temp)
    return temp
Enter fullscreen mode Exit fullscreen mode

This allows merging JPG/PNG.

Step 10 — Add Background Threading

Prevent UI freezing.

def start_merge(self):
    thread = threading.Thread(
        target=self.merge_pdfs,
        daemon=True
    )
    thread.start()
Enter fullscreen mode Exit fullscreen mode

Now UI remains responsive.

Step 11 — Add Progress Bar

self.progress = ttk.Progressbar(
    self.root,
    orient="horizontal",
    mode="determinate"
)
self.progress.pack(fill="x")
Enter fullscreen mode Exit fullscreen mode

Update during merge:

self.progress["value"] = percent
Enter fullscreen mode Exit fullscreen mode

Step 12 — Add Drag & Drop Support

from tkinterdnd2 import TkinterDnD, DND_FILES
Enter fullscreen mode Exit fullscreen mode

Register drop target:

self.listbox.drop_target_register(DND_FILES)
self.listbox.dnd_bind("<<Drop>>", self.on_drop)
Enter fullscreen mode Exit fullscreen mode

Handle dropped files:

def on_drop(self, event):
    files = self.root.tk.splitlist(event.data)
    for file in files:
        self.items.append(file)
        self.listbox.insert(tk.END, file)
Enter fullscreen mode Exit fullscreen mode

Step 13 — Add Page Editor

Allow rotate/delete pages.

def rotate_page(page):
    page.rotate(90)
Enter fullscreen mode Exit fullscreen mode

Delete pages:

writer = PdfWriter()

for i, page in enumerate(reader.pages):
    if i not in selected:
        writer.add_page(page)
Enter fullscreen mode Exit fullscreen mode

Step 14 — Add Theme Toggle

def toggle_theme(self):
    self.dark = not self.dark

    bg = "#1e1e2f" if self.dark else "#ffffff"
    self.root.configure(bg=bg)
Enter fullscreen mode Exit fullscreen mode

Step 15 — Final Main Function

def main():
    root = tk.Tk()
    app = PDFMateApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

Final Result

You now have a full desktop PDF tool:

✔ Merge PDFs
✔ Convert images
✔ Drag & drop
✔ Page editor
✔ Progress bar
✔ Threaded processing
✔ Theme toggle

Full Project

Complete production-ready code:

https://github.com/rogers-cyber/PDFMatePlus

What You Learned
Tkinter GUI
PDF merging
Image conversion
Threading
Drag & drop
Page editing
Desktop app architecture
Next Improvements

You can add:

PDF watermark
password protection
OCR
EXE build (PyInstaller)
auto update

Top comments (0)