2026-01-15

gpdf.py

pdftk 참 좋은데 명령어 방식이라 좀 불편. PyQt 활용. 간단한 기능만 GUI 버전으로 만들어 봄.

gpdf.py

import sys

import subprocess

from PyQt6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QPushButton, 

                             QListWidget, QFileDialog, QHBoxLayout, QMessageBox)

from PyQt6.QtCore import Qt


class PDFJoiner(QWidget):

    def __init__(self):

        super().__init__()

        self.initUI()


    def initUI(self):

        self.setWindowTitle('PDF 도우미 (pdftk GUI)')

        self.setGeometry(300, 300, 500, 400)


        layout = QVBoxLayout()


        # 파일 목록 표시창

        self.file_list = QListWidget()

        layout.addWidget(self.file_list)


        # 버튼 레이아웃

        btn_layout = QHBoxLayout()

        

        btn_add = QPushButton('파일 추가')

        btn_add.clicked.connect(self.add_files)

        

        btn_remove = QPushButton('삭제')

        btn_remove.clicked.connect(self.remove_item)


        btn_up = QPushButton('위로')

        btn_up.clicked.connect(lambda: self.move_item(-1))


        btn_down = QPushButton('아래로')

        btn_down.clicked.connect(lambda: self.move_item(1))


        btn_layout.addWidget(btn_add)

        btn_layout.addWidget(btn_remove)

        btn_layout.addWidget(btn_up)

        btn_layout.addWidget(btn_down)

        layout.addLayout(btn_layout)


        # 실행 버튼

        self.btn_run = QPushButton('PDF 합치기 실행')

        self.btn_run.setStyleSheet("background-color: #4CAF50; color: white; font-weight: bold; height: 40px;")

        self.btn_run.clicked.connect(self.merge_pdfs)

        layout.addWidget(self.btn_run)


        self.setLayout(layout)


    def add_files(self):

        files, _ = QFileDialog.getOpenFileNames(self, "PDF 파일 선택", "", "PDF Files (*.pdf)")

        if files:

            self.file_list.addItems(files)


    def remove_item(self):

        for item in self.file_list.selectedItems():

            self.file_list.takeItem(self.file_list.row(item))


    def move_item(self, direction):

        current_row = self.file_list.currentRow()

        if current_row < 0: return

        

        target_row = current_row + direction

        if 0 <= target_row < self.file_list.count():

            item = self.file_list.takeItem(current_row)

            self.file_list.insertItem(target_row, item)

            self.file_list.setCurrentRow(target_row)


    def merge_pdfs(self):

        count = self.file_list.count()

        if count < 2:

            QMessageBox.warning(self, "알림", "합칠 파일이 2개 이상 필요합니다.")

            return


        save_path, _ = QFileDialog.getSaveFileName(self, "저장 경로 선택", "merged_output.pdf", "PDF Files (*.pdf)")

        

        if save_path:

            input_files = [self.file_list.item(i).text() for i in range(count)]

            

            # pdftk 명령어 구성

            # pdftk file1.pdf file2.pdf cat output combined.pdf

            command = ["pdftk"] + input_files + ["cat", "output", save_path]

            

            try:

                subprocess.run(command, check=True)

                QMessageBox.information(self, "성공", f"성공적으로 합쳐졌습니다!\n경로: {save_path}")

            except Exception as e:

                QMessageBox.critical(self, "오류", f"실행 중 오류가 발생했습니다: {e}")


if __name__ == '__main__':

    app = QApplication(sys.argv)

    ex = PDFJoiner()

    ex.show()

    sys.exit(app.exec())