Существует множество приложений, которые выполняют задачи по работе с PDF-файлами намного лучше того, что сделал я. Но, ни одно из них не выполняет именно те задачи, которые нужны мне в комплексе (но это не точно). Хотелось бы рассказать вам свой опыт создания GUI-приложения для работы с PDF на Python с использованием в качестве дизайнера интерфейса PyQt.
Немного предыстории
Началось все с того, что мне понадобилось приложение, которое конвертирует страницы html в pdf формат. Именно те страницы, которые сохранены локально. И вроде бы, с этим может справиться любой браузер, достаточно только открыть страницу, запустить печать и сохранить как pdf. Но, что если у вас множество файлов хранящихся локально? Как долго будет длится их обработка? Потому мне требовалось приложение, которое сможет конвертировать все файлы в одной директории в автоматическом режиме. Так же, хотелось бы добавить функцию, чтобы оно умело объединять конвертированные файлы в один, а также уменьшать (или пытаться это сделать) размер полученного после объединения файла.
Думаю, что легко смог бы найти все необходимые мне приложения по отдельности, но мне хотелось, чтобы это был именно комбайн с нужными мне функциями. Также, хотелось, чтобы у него был GUI, а не командная строка. Немного подумав я решил ничего не искать, а сделать приложение для своих нужд самостоятельно и теперь делюсь тем, что у меня получилось. Ведь может быть, кому-то это будет полезно.
Что понадобиться?
Для того, чтобы объединять pdf-файлы нужно установить PyMuPDF. Также, для того, чтобы конвертировать html в pdf понадобиться установить обертку для библиотеки wkhtmltopdf — pdfkit. Также, для сжатия PDF-файлов нужно будет установить библиотеку PyPDF2. Собственно, так как у нас имеется графический интерфейс, нужно установить библиотеки pyqt5 и pyqt5-tools, для работы с ним. С данными библиотеками устанавливается Qt Designer, с помощью которого мы будем создавать интерфейс приложения. Для установки всего этого набора пишем в терминале команду:
GhostScript установлен в Linux по умолчанию (в Kali нет. Возможно еще в каких-то дистрибутивах), а вот wkhtmltopdf желательно установить. Потому, можно написать в терминале команду:
которая установит данный пакет. Однако, если вы этого не сделаете, при запуске приложения, которое мы будем писать далее, установка данного пакета будет запрошена в любом случае. Это так, небольшой спойлер )).
После того, как все библиотеки и пакеты будут установлены, импортируем их в наш скрипт:
Как видите, в самом конце импортируется модуль с графическим интерфейсом, который мы создали в дизайнере. У вас он может называться по другому, однако, для начала определим простую заготовку для будущего приложения. А заготовка будет выглядеть так:
Итак, теперь почти все готово для того, чтобы начать создавать приложение. Начнем мы с графического интерфейса. А потому, нужно найти путь, по которому лежит исполняемый файл дизайнера, для его запуска. У меня он такой: /Projects/new_pdf/venv/lib/python3.8/site-packages/qt5_applications/Qt/bin/designer.
Просто зайдите в папку вашего проекта, найдите папку виртуального окружения, а в ней уже все остальные папки. Хочу отметить, что файл дизайнера появиться в том случае, если вы установите pyqt5-tools. После того, как найдете файл, запускаете его и выбираете MainWindow, после чего жмете кнопку «Создать».
Создание интерфейса
В данном случае не буду в деталях описывать как и что я делал. Это в принципе не особо-то существенно. Важно показать вам интерфейс получившегося приложения и те компоненты, которые я накидал на форму. Также, описать как называется тот или иной компонент, чтобы было в дальнейшем понятно, к какому из них конкретно я обращаюсь в коде. А потому, вот интерфейс приложения:
На форму я добавил восемь кнопок, каждая из которых выполняет свою функцию. Однако, я добавлял не простые кнопки типа Push Button. Все эти кнопки имеют тип Tool Button. Выбраны они были потому, что для каждой кнопки можно установить собственную иконку без того, чтобы в коде основного модуля присваивать значение картинки кнопке. Поэтому, закидываем на форму кнопки, выделяем каждую и включаем свойство: autoRaise.
Затем переходим в раздел icon. Здесь ищем параметр «Активный, вкл», нажимаем на стрелочку вниз и выбираем пункт «Выбрать файл».
Учтите то, что файл изображения должен лежать или в папке со скриптом, или в папке со скриптом, в специально созданной папке для этих целей, например, как у меня: pic. Здесь я не стал идти по более трудоемкому пути, когда нужно было бы создавать файл ресурсов. В данном контексте мне хватает данного функционала, а папку с картинками перемещать или копировать с питоновским файлом не составит особого труда.
Теперь, что касается названия кнопок:
Также на форму добавлены два QComboBox. Первый комбо-бокс имеет название methodBox и служит для выбора метода сжатия, второй — ratioBox, служит для выбора степени сжатия, при выборе метода сжатия с помощью GhostScript.
Добавлен QLineEdit, с именем pathEdt. Нужен для отображения пути к директории с файлами. Имеет свойство Enabled в состоянии False, для того, чтобы нельзя было изменить его содержимое.
На форме, для отображения содержимого директории добавлена таблица QTableWidget с именем fileView. В таблице имеется только один столбец, хотя, этого достаточно для отображения имен файлов. Однако, если у вас есть желание, можете добавить еще один столбец, в котором будете хранить путь к файлу. Но в этом случае, логику добавления записей в таблицу потребуется немного изменить.
И наконец, добавлен QProgressBar с именем progressBar, нужен для отображения прогресса конвертации, объединения и прочих прогрессов.
Сохранение формы и конвертация в формат файла py
После того, как все нужные компоненты будут добавлены на форму, нужно ее сохранить в папке с вашим скриптом, то есть, в рабочей директории. Я сохранил ее с именем mergepdf.ui. После этого запускаем в терминале команду для конвертации формы в питоновский модуль, который можно будет импортировать в приложение:
Вот и все, теперь форма готова для того, чтобы импортировать ее в приложение. Если помните, то в самом начале, в импорте, это и было сделано:
Теперь можно приступать писать логику приложения. Всю логику я уместил в одном модуле, потому, дополнительных создавать не нужно. Конечно, код получился несколько длинноват, но мне хотелось, чтобы не требовалось таскать с собой по диску несколько модулей. А чтобы все было в одном.
А на этом первую часть завершаю. Код приложения будем писать в следующей части.
Созданный ui, иконки и файл с шаблоном я прикреплю во вложении. Так что, можно просто скачать то, что там и открыть в дизайнере.
Спасибо за внимание. Надеюсь, что данная информация будет вам полезна
Немного предыстории
Началось все с того, что мне понадобилось приложение, которое конвертирует страницы html в pdf формат. Именно те страницы, которые сохранены локально. И вроде бы, с этим может справиться любой браузер, достаточно только открыть страницу, запустить печать и сохранить как pdf. Но, что если у вас множество файлов хранящихся локально? Как долго будет длится их обработка? Потому мне требовалось приложение, которое сможет конвертировать все файлы в одной директории в автоматическом режиме. Так же, хотелось бы добавить функцию, чтобы оно умело объединять конвертированные файлы в один, а также уменьшать (или пытаться это сделать) размер полученного после объединения файла.
Думаю, что легко смог бы найти все необходимые мне приложения по отдельности, но мне хотелось, чтобы это был именно комбайн с нужными мне функциями. Также, хотелось, чтобы у него был GUI, а не командная строка. Немного подумав я решил ничего не искать, а сделать приложение для своих нужд самостоятельно и теперь делюсь тем, что у меня получилось. Ведь может быть, кому-то это будет полезно.
Что понадобиться?
Для того, чтобы объединять pdf-файлы нужно установить PyMuPDF. Также, для того, чтобы конвертировать html в pdf понадобиться установить обертку для библиотеки wkhtmltopdf — pdfkit. Также, для сжатия PDF-файлов нужно будет установить библиотеку PyPDF2. Собственно, так как у нас имеется графический интерфейс, нужно установить библиотеки pyqt5 и pyqt5-tools, для работы с ним. С данными библиотеками устанавливается Qt Designer, с помощью которого мы будем создавать интерфейс приложения. Для установки всего этого набора пишем в терминале команду:
pip install pyqt5 pyqt5-tools PyPDF2 pdfkit PyMuPDF
GhostScript установлен в Linux по умолчанию (в Kali нет. Возможно еще в каких-то дистрибутивах), а вот wkhtmltopdf желательно установить. Потому, можно написать в терминале команду:
sudo apt-get install wkhtmltopdf
которая установит данный пакет. Однако, если вы этого не сделаете, при запуске приложения, которое мы будем писать далее, установка данного пакета будет запрошена в любом случае. Это так, небольшой спойлер )).
После того, как все библиотеки и пакеты будут установлены, импортируем их в наш скрипт:
Python:
import os.path
import shutil
import subprocess
import sys
from os import system
from pathlib import Path
import fitz
import pdfkit
from PyPDF2 import PdfFileReader, PdfFileWriter
from PyQt5.QtWidgets import QLineEdit
from mergepdf import *
Как видите, в самом конце импортируется модуль с графическим интерфейсом, который мы создали в дизайнере. У вас он может называться по другому, однако, для начала определим простую заготовку для будущего приложения. А заготовка будет выглядеть так:
Python:
class MyWin(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.path_file = None
# здесь функции класса
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
myapp = MyWin()
myapp.show()
sys.exit(app.exec_())
Итак, теперь почти все готово для того, чтобы начать создавать приложение. Начнем мы с графического интерфейса. А потому, нужно найти путь, по которому лежит исполняемый файл дизайнера, для его запуска. У меня он такой: /Projects/new_pdf/venv/lib/python3.8/site-packages/qt5_applications/Qt/bin/designer.
Просто зайдите в папку вашего проекта, найдите папку виртуального окружения, а в ней уже все остальные папки. Хочу отметить, что файл дизайнера появиться в том случае, если вы установите pyqt5-tools. После того, как найдете файл, запускаете его и выбираете MainWindow, после чего жмете кнопку «Создать».
Создание интерфейса
В данном случае не буду в деталях описывать как и что я делал. Это в принципе не особо-то существенно. Важно показать вам интерфейс получившегося приложения и те компоненты, которые я накидал на форму. Также, описать как называется тот или иной компонент, чтобы было в дальнейшем понятно, к какому из них конкретно я обращаюсь в коде. А потому, вот интерфейс приложения:
На форму я добавил восемь кнопок, каждая из которых выполняет свою функцию. Однако, я добавлял не простые кнопки типа Push Button. Все эти кнопки имеют тип Tool Button. Выбраны они были потому, что для каждой кнопки можно установить собственную иконку без того, чтобы в коде основного модуля присваивать значение картинки кнопке. Поэтому, закидываем на форму кнопки, выделяем каждую и включаем свойство: autoRaise.
Затем переходим в раздел icon. Здесь ищем параметр «Активный, вкл», нажимаем на стрелочку вниз и выбираем пункт «Выбрать файл».
Учтите то, что файл изображения должен лежать или в папке со скриптом, или в папке со скриптом, в специально созданной папке для этих целей, например, как у меня: pic. Здесь я не стал идти по более трудоемкому пути, когда нужно было бы создавать файл ресурсов. В данном контексте мне хватает данного функционала, а папку с картинками перемещать или копировать с питоновским файлом не составит особого труда.
Теперь, что касается названия кнопок:
Код:
folderBtn — кнопка для открытия директории с файлами, первая кнопка с папкой;
convertBtn — кнопка для конвертирования html в pdf, вторая кнопка со стрелками;
mergeBtn — кнопка для объединения файлов pdf, третья кнопка с соединяющимися листочками;
compressBtn — кнопка для запуска сжатия pdf-файлов, четвертая кнопка с тисками;
exitBtn — кнопка для выхода из приложения, пятая кнопка с дверью;
upBtn — кнопка для перемещения строки вверх, шестая кнопка со стрелкой вверх;
dwnBtn — кнопка для перемещения строки вниз, седьмая кнопка со стрелкой вниз;
delBtn — кнопка для удаления строки, восьмая кнопка с корзиной.
Также на форму добавлены два QComboBox. Первый комбо-бокс имеет название methodBox и служит для выбора метода сжатия, второй — ratioBox, служит для выбора степени сжатия, при выборе метода сжатия с помощью GhostScript.
Добавлен QLineEdit, с именем pathEdt. Нужен для отображения пути к директории с файлами. Имеет свойство Enabled в состоянии False, для того, чтобы нельзя было изменить его содержимое.
На форме, для отображения содержимого директории добавлена таблица QTableWidget с именем fileView. В таблице имеется только один столбец, хотя, этого достаточно для отображения имен файлов. Однако, если у вас есть желание, можете добавить еще один столбец, в котором будете хранить путь к файлу. Но в этом случае, логику добавления записей в таблицу потребуется немного изменить.
И наконец, добавлен QProgressBar с именем progressBar, нужен для отображения прогресса конвертации, объединения и прочих прогрессов.
Сохранение формы и конвертация в формат файла py
После того, как все нужные компоненты будут добавлены на форму, нужно ее сохранить в папке с вашим скриптом, то есть, в рабочей директории. Я сохранил ее с именем mergepdf.ui. После этого запускаем в терминале команду для конвертации формы в питоновский модуль, который можно будет импортировать в приложение:
pyuic5 mergepdf.ui -o mergepdf.py
Вот и все, теперь форма готова для того, чтобы импортировать ее в приложение. Если помните, то в самом начале, в импорте, это и было сделано:
from mergepdf import *
Теперь можно приступать писать логику приложения. Всю логику я уместил в одном модуле, потому, дополнительных создавать не нужно. Конечно, код получился несколько длинноват, но мне хотелось, чтобы не требовалось таскать с собой по диску несколько модулей. А чтобы все было в одном.
А на этом первую часть завершаю. Код приложения будем писать в следующей части.
Созданный ui, иконки и файл с шаблоном я прикреплю во вложении. Так что, можно просто скачать то, что там и открыть в дизайнере.
Спасибо за внимание. Надеюсь, что данная информация будет вам полезна
Вложения
Последнее редактирование: