
FileFusion - Python Pdf Converter
Over the past few weeks, Iβve been developing FileFusion, a desktop application built with Python and Qt (PyQt5), designed to convert and merge files into PDFs in a clean, intuitive interface.
This project was both a technical deep dive and a UI/UX exercise, combining threaded background processing, file I/O handling, and dynamic Qt widgets to deliver a professional-grade user experience.
Overviewπ§©
FileFusion allows users to:
- ποΈ Convert
.doc
,.docx
, and common image formats (.png
,.jpg
,.bmp
,.tiff
) to PDF - π Merge multiple PDFs into a single document
- βοΈ Track progress and conversion logs in real time
- π±οΈ Drag and drop files directly into the app
- π§ Handle both single and batch operations smoothly
The appβs UI adapts dynamically based on context, showing or hiding widgets such as the merge checkbox or output folder selector.
Architecture ποΈ
The app follows a modular MVC-like structure, with a clean separation between the engine (conversion logic) and the UI (PyQt5 front-end):
π Project Structure
βββ converter_engine.py # Core conversion and merging logic
βββ app.py # Main window, threading, and UI logic
βββ main_window_ui.py # Generated PyQt5 UI file
βββ preview_window.py # PDF preview dialog
βββ resources/
βββ icons/
βββ styles.qss
Core Processing π§
At the heart of the system is the ConverterEngine
class, a self-contained conversion and merge manager.
It supports:
- Document Conversion using
docx2pdf
- Image Conversion with
Pillow
- PDF Merging via
PyPDF2.PdfMerger
- Progress Feedback through callback functions
Each conversion operation is saved to a temporary file, logged, and a cleanup system ensures this temporary files are properly deleted, even after errors.
def _cleanup(self, file_paths: List[str]):
"""Removes temporary files."""
for path in file_paths:
try:
os.remove(path)
logging.info(f"Cleaned up temporary file: {path}")
except OSError as e:
logging.error(f"Error cleaning up file {path}: {e}")
Threading & Responsiveness π§΅
To keep the UI responsive, long-running conversions are handled on a background thread via a dedicated Worker
object that
communicates with the main thread using Qt signals:
class Worker(QObject):
finished = pyqtSignal(bool, str, str)
progress = pyqtSignal(int)
status_update = pyqtSignal(str)
This allows real-time updates to the:
- Progress bar
- Status label
- Log messages
without blocking the main event loop.
User Interface & UX π¨
The interface, built with Qt Designer

The style is designed around a dark, modern theme with a clear focus on usability:
- Drag-and-drop support for quick file input
- Dynamic widget visibility depending on user actions (e.g., merge mode hides output folder input)
- Consistent visual hierarchy using custom Qt stylesheet:
self.setStyleSheet("""
QWidget { background-color: #2b2b2b; color: #ffffff; font-family: Segoe UI; }
QPushButton { background-color: #0078d7; border-radius: 4px; }
QPushButton:hover { background-color: #005a9e; }
QProgressBar::chunk { background-color: #0078d7; border-radius: 4px; }
""")
The visual result is the following:


Design Decisions π§
A few important implementation choices:
- Threaded Processing
Avoids freezing the UI and supports real-time progress reporting. - Signal-based Communication
Keeps background logic decoupled from UI updates, a must for Qt apps. - Flexible Output Handling
Theconvert_to_pdf()
method now supports an optional output directory argument, ensuring clean separation between merge workflows and individual conversions. - Automatic Resource Cleanup
Temporary PDFs used for merging are safely deleted after completion to prevent file clutter.
Challenges & Lessons Learned π§ͺ
- Thread-safe logging required a custom Qt log handler that emits status updates to the GUI safely.
- PDF merging with
PyPDF2
needed careful file handling (binary mode, file handles closed properly). - Progress reporting had to work seamlessly across mixed file types and dynamic workloads.
Tech Stack π§°
Component | Library |
---|---|
GUI | PyQt5 |
File Conversion | docx2pdf , Pillow |
PDF Merging | PyPDF2 |
Logging | Python logging module |
Threading | QThread + custom QObject worker |
Takeaway π
FileFusion was an excellent exercise in desktop application engineering with Python, balancing real-world file operations,
asynchronous workflows, and user experience design.
Itβs open for future extension, and demonstrates how Python
, when combined with Qt
, can produce clean, professional-grade applications beyond the command line.
Try it yourself !
If you want to try it, you can download it directly from here, unzip, and launch the .exe
Please note that this .exe
might fire security warnings. This is a normal behaviour since this little app hasnβt been signed through a Certificate Authority (CA).