利用pyqt5和PyPDF2实现pdf文件的合并

基于PyQt5的PDF文件合并与选择工具,
该文章详细描述了一个使用Python和PyQt5构建的程序,用于合并PDF文件,支持文件选择、页数设置等功能。
# -*- coding: utf-8 -*-
import sys

from PyPDF2 import PdfReader, PdfWriter
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QMessageBox

import hebing2

class Ui_MainWindow (object):
    file_box = []
    def setupUi(self, MainWindow):
        MainWindow.setObjectName ("PDF合并")
        MainWindow.resize (1478, 916)
        MainWindow.setMinimumSize (QtCore.QSize (1478, 916))
        MainWindow.setMaximumSize (QtCore.QSize (1478, 916))
        self.centralwidget = QtWidgets.QWidget (MainWindow)
        self.centralwidget.setObjectName ("centralwidget")
        self.all_choose = QtWidgets.QCheckBox (self.centralwidget)
        self.all_choose.setGeometry (QtCore.QRect (40, 20, 142, 42))
        self.all_choose.setObjectName ("all_choose")
        self.all_choose.clicked.connect(lambda :self.choose_all_checkbox())

        # 添加文件 按钮
        self.add_file = QtWidgets.QPushButton (self.centralwidget)
        self.add_file.setGeometry (QtCore.QRect (200, 560, 1262, 46))
        self.add_file.setObjectName ("add_file")
        self.add_file.setCheckable (True)
        self.add_file.clicked.connect (lambda: self.click_button (self.add_file))

        self.clear_but = QtWidgets.QPushButton (self.centralwidget)
        self.clear_but.setGeometry (QtCore.QRect (20, 560, 150, 46))
        self.clear_but.setObjectName ("clear_but")
        self.clear_but.setCheckable (True)
        self.clear_but.clicked.connect (lambda: self.click_button (self.clear_but))

        #合并文件不需要这个按钮
        self.output_name_but = QtWidgets.QPushButton (self.centralwidget)
        self.output_name_but.setGeometry (QtCore.QRect (20, 680, 150, 46))
        self.output_name_but.setObjectName ("output_name_but")

        self.output_dir_but = QtWidgets.QPushButton (self.centralwidget)
        self.output_dir_but.setGeometry (QtCore.QRect (20, 620, 150, 46))
        self.output_dir_but.setObjectName ("output_dir_but")
        self.output_dir_but.setCheckable(True)
        self.output_dir_but.clicked.connect(lambda :self.click_button (self.output_dir_but))

        #也不需要这个控件
        self.output_name_edit = QtWidgets.QLineEdit (self.centralwidget)
        self.output_name_edit.setGeometry (QtCore.QRect (200, 680, 1262, 40))
        self.output_name_edit.setObjectName ("output_name_edit")

        self.output_dir_edit = QtWidgets.QLineEdit (self.centralwidget)
        self.output_dir_edit.setGeometry (QtCore.QRect (200, 620, 1262, 40))
        self.output_dir_edit.setObjectName ("output_dir_edit")
        self.start_but = QtWidgets.QPushButton (self.centralwidget)
        self.start_but.setGeometry (QtCore.QRect (1200, 740, 262, 82))
        self.start_but.setObjectName ("start_but")
        self.start_but.setCheckable(True)
        self.start_but.clicked.connect(lambda :self.click_button (self.start_but))

        self.page_number = QtWidgets.QLabel (self.centralwidget)
        self.page_number.setGeometry (QtCore.QRect (940, 20, 82, 40))
        self.page_number.setObjectName ("page_number")
        self.operate = QtWidgets.QLabel (self.centralwidget)
        self.operate.setGeometry (QtCore.QRect (1300, 20, 142, 32))
        self.operate.setLayoutDirection (QtCore.Qt.LeftToRight)
        self.operate.setAlignment (QtCore.Qt.AlignCenter)
        self.operate.setObjectName ("operate")
        self.choose_page = QtWidgets.QLabel (self.centralwidget)
        self.choose_page.setGeometry (QtCore.QRect (1140, 20, 142, 32))
        self.choose_page.setLayoutDirection (QtCore.Qt.LeftToRight)
        self.choose_page.setAlignment (QtCore.Qt.AlignCenter)
        self.choose_page.setObjectName ("choose_page")

        # frame 和frame里面的部分空间设置
        self.frame = QtWidgets.QFrame (self.centralwidget)
        self.frame.setGeometry (QtCore.QRect (20, 60, 1442, 482))
        self.frame.setMouseTracking (False)
        self.frame.setTabletTracking (False)
        self.frame.setLayoutDirection (QtCore.Qt.LeftToRight)
        self.frame.setAutoFillBackground (False)
        self.frame.setFrameShape (QtWidgets.QFrame.Box)
        self.frame.setFrameShadow (QtWidgets.QFrame.Raised)
        self.frame.setLineWidth (1)
        self.frame.setMidLineWidth (1)
        self.frame.setObjectName ("frame")

        MainWindow.setCentralWidget (self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar (MainWindow)
        self.statusbar.setObjectName ("statusbar")
        MainWindow.setStatusBar (self.statusbar)
        self.menuBar = QtWidgets.QMenuBar (MainWindow)
        self.menuBar.setGeometry (QtCore.QRect (0, 0, 1478, 44))
        self.menuBar.setObjectName ("menuBar")
        self.hebing = QtWidgets.QMenu (self.menuBar)
        self.hebing.setObjectName ("hebing")
        # self.fenge = QtWidgets.QMenu (self.menuBar)
        # self.fenge.setObjectName ("fenge")
        MainWindow.setMenuBar (self.menuBar)
        self.menuBar.addAction (self.hebing.menuAction ())
        # self.menuBar.addAction (self.fenge.menuAction ())

        self.retranslateUi (MainWindow)
        QtCore.QMetaObject.connectSlotsByName (MainWindow)
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle (_translate ("MainWindow", "PDF合并"))
        self.all_choose.setText (_translate ("MainWindow", "名称"))
        self.add_file.setText (_translate ("MainWindow", "添加文件"))
        self.clear_but.setText (_translate ("MainWindow", "清除所选"))
        self.output_name_but.setText (_translate ("MainWindow", "输出名称"))
        self.output_dir_but.setText (_translate ("MainWindow", "输出目录"))
        self.start_but.setText (_translate ("MainWindow", "开始操作"))
        self.page_number.setText (_translate ("MainWindow", " 页数"))
        self.operate.setText (_translate ("MainWindow", "操作"))
        self.choose_page.setText (_translate ("MainWindow", "选择范围"))
        self.hebing.setTitle (_translate ("MainWindow", "合并"))
        #self.fenge.setTitle (_translate ("MainWindow", "分割"))
    # 创建一个list用于存放输入的文件和其相关信息
    def choose_all_checkbox(self):
        if self.all_choose.isChecked():
            for i in self.file_box:
                i[2].setChecked(True)
        else:
            for i in self.file_box:
                i[2].setChecked(False)
    def choose_all_by_others(self):
        num1 = 0
        num2 = 0
        for i in self.file_box:
            if i[2].isChecked():
                num1 += 1
            else:
                num2 += 1

        if num1 == len(self.file_box):
            self.all_choose.setChecked(True)

        if num2 != 0:
            self.all_choose.setChecked(False)

    def show_message_box(self):
        reply = QMessageBox.information (self, '提示', '数量超限,请不要添加超过9个文件.', QMessageBox.Ok)

    def add_data(self,date_path):
        if len (self.file_box)>8:
            self.show_message_box()
            return
        file_info = []
        m1 = date_path
        pdf_name = m1[0].split ("/")[-1]
        # file_info第一个信息是文件地址
        file_info.append (m1[0])
        # 获取pdf的页数
        pdf = PdfReader (m1[0])

        x = 20 + len (self.file_box) * 50

        path = QtWidgets.QCheckBox (self.frame)
        path.setGeometry (QtCore.QRect (20, x, 782, 42))
        path.setVisible (True)
        path.setCheckable (True)
        path.clicked.connect (lambda: self.choose_all_by_others ())

        # 文件的页数
        page_num_2 = QtWidgets.QLineEdit (self.frame)
        page_num_2.setGeometry (QtCore.QRect (880, x, 162, 40))
        page_num_2.setVisible (True)

        choose_page_s2 = QtWidgets.QLineEdit (self.frame)
        choose_page_s2.setGeometry (QtCore.QRect (1080, x, 100, 40))
        choose_page_s2.setVisible (True)

        choose_page_e2 = QtWidgets.QLineEdit (self.frame)
        choose_page_e2.setGeometry (QtCore.QRect (1200, x, 100, 40))
        choose_page_e2.setVisible (True)

        up_2 = QtWidgets.QPushButton (self.frame)
        up_2.setGeometry (QtCore.QRect (1320, x, 32, 46))
        up_2.setText ("⬆️")
        up_2.setVisible (True)
        up_2.setCheckable (True)
        up_2.clicked.connect (lambda: self.click_button (up_2))

        down_2 = QtWidgets.QPushButton (self.frame)
        down_2.setGeometry (QtCore.QRect (1360, x, 32, 46))
        down_2.setText ("⬇️")
        down_2.setVisible (True)
        down_2.setCheckable (True)
        down_2.clicked.connect (lambda: self.click_button (down_2))

        # 将pdf页数发送到对应位置
        page_num_2.setText (str (len (pdf.pages)))
        # file_info第二个信息是页数
        file_info.append (str (len (pdf.pages)))

        # 默认选择范围为开始和结束页
        choose_page_s2.setText ("1")
        choose_page_e2.setText (str (len (pdf.pages)))
        # 将文件的缩略文件名写入复选框的text中
        if len (pdf_name) > 30:
            pdf_name = pdf_name[:15] + "..." + pdf_name[-10:]
            path.setText (pdf_name)
        else:
            path.setText (pdf_name)
        file_info.append (path)
        file_info.append (page_num_2)
        file_info.append (choose_page_s2)
        file_info.append (choose_page_e2)
        file_info.append (up_2)
        file_info.append (down_2)

        # 将数据存入file_box中统一管理
        self.file_box.append (file_info)
    def reshow_file_box(self):
        row_num = 0
        for i in range (len (self.file_box)):
            col_num = 0
            for j in self.file_box[i][2:]:
                if col_num == 0:
                    j.setGeometry (QtCore.QRect (20, 20 + row_num * 50, 782, 42))
                    col_num = col_num + 1
                elif col_num == 1:
                    j.setGeometry (QtCore.QRect (880, 20 + row_num * 50, 162, 40))
                    col_num = col_num + 1
                elif col_num == 2:
                    j.setGeometry (QtCore.QRect (1080, 20 + row_num * 50, 100, 40))
                    col_num = col_num + 1
                elif col_num == 3:
                    j.setGeometry (QtCore.QRect (1200, 20 + row_num * 50, 100, 40))
                    col_num = col_num + 1
                elif col_num == 4:
                    j.setGeometry (QtCore.QRect (1320, 20 + row_num * 50, 32, 46))
                    col_num = col_num + 1
                elif col_num == 5:
                    j.setGeometry (QtCore.QRect (1360, 20 + row_num * 50, 32, 46))
            row_num = row_num + 1
    # 把所有的按钮都放在一个办法中去处理对应的情况,
    def click_button(self, button):
        if button.text () == "添加文件":
            if button.isChecked ():
                m1 = QtWidgets.QFileDialog.getOpenFileName (None, "选择文件")
                if m1[0] == "":
                    button.setChecked (False)
                    return
                self.add_data(m1)
                button.setChecked (False)
        if button.text () == "清除所选":
            if button.isChecked ():
                checked_list = []
                for i in range (len (self.file_box)):
                    if self.file_box[i][2].isChecked ():
                        checked_list.append(self.file_box[i])
                        for j in self.file_box[i][2:]:
                            j.setVisible (False)
                for i in checked_list:
                    self.file_box.remove(i)
                self.reshow_file_box ()
                button.setChecked (False)
        if button.text () == "输出目录":
            if button.isChecked ():
                m1 = QtWidgets.QFileDialog.getExistingDirectory(None, "输出目录")
                print(m1)
                if m1 == "":
                    button.setChecked (False)
                    return
                self.output_dir_edit.setText(m1)
            button.setChecked(False)
        if button.text () == "开始操作":
            if button.isChecked():
                if self.output_name_edit.text() == "":
                    button.setChecked(False)
                    return
                elif self.output_dir_edit.text() == "":
                    button.setChecked(False)
                    return
                elif len (self.file_box) == 0:
                    button.setChecked(False)
                    return
                else:
                    state = 0
                    for i in self.file_box:
                        if i[2].isChecked ():
                            state = 1
                            break
                    if state == 0:
                        button.setChecked(False)
                        return
                    ls_list = []
                    for i in self.file_box:
                        if i[2].isChecked():
                            ls_list.append(i)
                    hebing2.split_pdf(ls_list,self.output_dir_edit.text()+"/"+self.output_name_edit.text()+".pdf")
                    button.setChecked(False)
        if button.text () == "⬆️":
            if button.isChecked():
                for i in range(len(self.file_box)):
                    if button in self.file_box[i]:
                        if i == 0:
                            button.setChecked (False)
                            return
                        else:
                            self.file_box[i] , self.file_box[i-1] = self.file_box[i-1] ,self.file_box[i]
                self.reshow_file_box()
                button.setChecked(False)
        if button.text () == "⬇️":
            if button.isChecked():
                for i,j in enumerate(self.file_box):
                    if j[7] == button:
                        if i < len (self.file_box)-1:
                            self.file_box[i] ,self.file_box[i+1] = self.file_box[i+1] ,self.file_box[i]
                            break
                        else:
                            button.setChecked(False)
                            return
                self.reshow_file_box ()
                button.setChecked(False)
class DragChangeWin(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(DragChangeWin, self).__init__(parent)
        self.setupUi(self)
        # 调用Drops方法
        self.setAcceptDrops(True)
    # 鼠标进入
    def dragEnterEvent(self, evn):
        # 鼠标放开函数事件
        if evn.mimeData ().hasUrls ():
            evn.acceptProposedAction ()
    # 鼠标放开
    def dropEvent(self, evn):
        files = [u.toLocalFile () for u in evn.mimeData ().urls ()]
        for i in files:
            m1 = [i]
            self.add_data(m1)

    # 鼠标拖动
    def dragMoveEvent(self, evn):
        pass

if __name__ == '__main__':
    # app初始化
    window = QApplication(sys.argv)
    dragWin = DragChangeWin()
    dragWin.show()
    dragWin.setFixedSize(dragWin.width(), dragWin.height())
    sys.exit(window.exec_())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值