PDF图纸重命名小工具

# main.pyw

import sys
from designer.designer import Ui_Form
from PyQt5.QtWidgets import QApplication,QMainWindow

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui_components = Ui_Form()
    ui_components.init_component()
    ui_components.show()
    sys.exit(app.exec_())

# ./designer/designer.py

from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtGui import QKeySequence
from PyQt5.QtWidgets import QWidget,QShortcut,QGridLayout,QFrame,QPushButton,QLabel
from .PdfFunction import PdfQueue,PdfInfo
from PIL.ImageQt import toqpixmap


class Ui_Form(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.pdf_queue: PdfQueue=None
        self.lastpdfinfo: PdfInfo=None
        self.curpdfinfo: PdfInfo=None

    def init_component(self):
        # self.resize(640,480)

        # 用来显示图片的label
        self.lbl_pic=MyLabel(self)
        self.lbl_pic.setMinimumSize(800,800)

        # 用来显示当前文件名称的label
        self.lbl_curfile=QtWidgets.QLabel()

        # 用来显示上一个文件名称的label
        self.lbl_lastfile=QtWidgets.QLabel()

        # 文本框
        self.lnedt_rename=QtWidgets.QLineEdit()
        self.lnedt_rename.setMinimumSize(300,150)
        self.lnedt_rename.setMaximumSize(300,150)

        # 上一个按钮
        self.btn_last=QtWidgets.QPushButton()
        self.btn_last.setMinimumHeight(100)

        # 下一个按钮
        self.btn_next=QtWidgets.QPushButton()
        self.btn_next.setMinimumHeight(100)

        # 全图显示按钮
        self.btn_full=QtWidgets.QPushButton()
        self.btn_full.setMinimumHeight(100)

        # 旋转按钮
        self.btn_rotate=QtWidgets.QPushButton()
        self.btn_rotate.setMinimumHeight(100)

        self.btn_last.setStyleSheet('QPushButton{background:#dddddd}')
        self.btn_next.setStyleSheet('QPushButton{background:#dddddd}')
        self.btn_full.setStyleSheet('QPushButton{background:#dddddd}')
        self.btn_rotate.setStyleSheet('QPushButton{background:#dddddd}')

        QShortcut(QKeySequence("Up"),self).activated.connect(self.btn_last.click)
        QShortcut(QKeySequence("Down"),self).activated.connect(self.btn_next.click)
        QShortcut(QKeySequence("Ctrl+F"),self).activated.connect(self.btn_full.click)
        QShortcut(QKeySequence("Ctrl+R"),self).activated.connect(self.btn_rotate.click)

        grid_layout=QGridLayout(self)
        grid_layout.setSpacing(5)
        grid_layout.addWidget(self.lbl_pic,0,0,7,1)
        grid_layout.addWidget(self.btn_last,0,1)
        grid_layout.addWidget(self.btn_next,1,1)
        grid_layout.addWidget(self.btn_rotate,2,1)
        grid_layout.addWidget(self.btn_full,3,1)
        grid_layout.addWidget(self.lbl_lastfile,4,1)
        grid_layout.addWidget(self.lbl_curfile,5,1)
        grid_layout.addWidget(self.lnedt_rename,6,1)

        for lbl in self.findChildren(QLabel):
            lbl.setFrameShape(QFrame.Box)
            lbl.setFrameShadow(QFrame.Raised)

        for btn in self.findChildren(QPushButton):
            btn.setEnabled(False)
        self.lnedt_rename.setEnabled(False)

        self.AddMyEvent()

        self.retranslateUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)

    def AddMyEvent(self):
        self.btn_last.clicked.connect(self.goto_last)
        self.btn_next.clicked.connect(self.goto_next)
        self.btn_rotate.clicked.connect(self.rotate_pic)
        self.btn_full.clicked.connect(self.full_pic)
        self.lnedt_rename.returnPressed.connect(self.rename_pdffile)

    def pdf_queue_init(self):
        for btn in self.findChildren(QPushButton):
            btn.setEnabled(True)
        self.btn_last.setEnabled(False)
        self.lnedt_rename.setEnabled(True)
        self.goto_next()

    def rename_pdffile(self):
        pdfinfo=self.pdf_queue.read_now()
        string=self.lnedt_rename.text()
        if string!='':
            pdfinfo.rename(string)

    def goto_next(self):
        self.btn_next.setEnabled(False)
        self.lastpdfinfo=self.pdf_queue.read_now()  # 当index==-1时,返回None
        self.curpdfinfo=self.pdf_queue.read_next()
        self.set_change()
        self.btn_next.setEnabled(True)

    def goto_last(self):
        self.btn_last.setEnabled(False)
        self.lastpdfinfo=self.pdf_queue.read_now()  # 当index==-1时,返回None
        self.curpdfinfo=self.pdf_queue.read_last()
        self.set_change()
        self.btn_last.setEnabled(True)

    def set_change(self):
        if self.lastpdfinfo:
            self.lbl_lastfile.setText('上一个:'+self.lastpdfinfo.file_name)
        if self.curpdfinfo:
            self.lbl_curfile.setText('当 前:'+self.curpdfinfo.file_name)
            self.setWindowTitle(self.curpdfinfo.file_path)
            self.set_pic()
        if self.pdf_queue.has_last():
            self.btn_last.setEnabled(True)
            self.btn_last.setStyleSheet('QPushButton{background:#dddddd}')
        else:
            self.btn_last.setEnabled(False)
            self.btn_last.setStyleSheet('QPushButton{background:#444444}')
        if self.pdf_queue.has_next():
            self.btn_next.setEnabled(True)
            self.btn_next.setStyleSheet('QPushButton{background:#dddddd}')
        else:
            self.btn_next.setEnabled(False)
            self.btn_next.setStyleSheet('QPushButton{background:#444444}')
        self.lnedt_rename.setText('')

    def full_pic(self):
        self.btn_full.setEnabled(False)
        self.pdf_queue.read_now().tick_full()
        self.btn_full.setEnabled(True)

    def rotate_pic(self):
        self.btn_rotate.setEnabled(False)
        self.pdf_queue.read_now().rotate_clockwise_90()
        self.btn_rotate.setEnabled(True)

    def set_pic(self):
        self.lbl_pic.setPixmap(toqpixmap(self.curpdfinfo.get_image()))

    def retranslateUi(self,Form):
        _translate=QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form","Form"))
        self.btn_rotate.setText(_translate("Form","旋转&Ctrl+R"))
        self.btn_full.setText(_translate("Form","全图&Ctrl+F"))
        self.btn_next.setText(_translate("Form","下一个&Down"))
        self.btn_last.setText(_translate("Form","上一个&Up"))


class MyLabel(QtWidgets.QLabel):
    def __init__(self,parent: Ui_Form):
        super(MyLabel,self).__init__()
        self.setAcceptDrops(True)
        self.setScaledContents(True)

        self.parent=parent

    def dragEnterEvent(self,a0: QtGui.QDragEnterEvent) -> None:
        if a0.mimeData().hasText():
            a0.accept()
        else:
            a0.ignore()

    def dropEvent(self,a0: QtGui.QDropEvent) -> None:
        # 如果触发事件的文本资源以‘file:’开头,那么进行一下逻辑
        # 将字符串中的'%23'替换成'#'
        # 将'file:///'前缀(本地)和'file:'前缀(局域网)消除掉
        text=a0.mimeData().text()
        if text.startswith('file:'):
            if text.find('\n')==-1:
                text+='\n'
            lines=text.split('\n')[:-1]
            lines=[string.replace('%23','#') for string in lines]
            lines=[string[5:] if string[7]!='/' else string[8:] for string in lines]
            # 仅接受PDF
            lines=[string for string in lines if string.lower().endswith('.pdf')]
            if lines:
                self.parent.pdf_queue=PdfQueue(lines,self.parent)
                self.parent.pdf_queue.initilized.emit()

# ./designer/PdfFunction.py

import os
import fitz
from PIL import Image
from PyQt5.QtCore import pyqtSignal,QObject


def page2PIL_Image(page: fitz.Page,dpi=150,colorspace=fitz.csGRAY,clip=None,alpha=False,annots=False):
    pixmap=page.get_pixmap(
        matrix=fitz.IdentityMatrix,
        dpi=dpi,
        colorspace=colorspace,
        clip=clip,
        alpha=alpha,
        annots=annots
    )
    return Image.frombuffer('L',(pixmap.width,pixmap.height),pixmap.samples)


def pdf2image(file_path,rotation,full_output):
    w_clip=420
    h_clip=630
    try:
        with fitz.open(file_path) as doc:
            x0=doc[0].cropbox.x0
            y0=doc[0].cropbox.y0
            x1=doc[0].cropbox.x1
            y1=doc[0].cropbox.y1
            w,h=x1-x0,y1-y0
            if rotation==90 or rotation==270:
                w,h=h,w
            doc[0].set_rotation(rotation)
            if full_output:
                return page2PIL_Image(doc[0])
            return page2PIL_Image(
                doc[0],clip=fitz.IRect(w-w_clip,h-h_clip,w-40,h-40))

    except Exception as e:
        print('pdf2image',e)


class PdfInfo(QObject):
    current_name=['','','']
    renameSignal=pyqtSignal()
    rotateSignal=pyqtSignal()
    fullSignal=pyqtSignal()

    def __init__(self,file_path,parent):
        QObject.__init__(self)
        self.parent=parent
        self.file_path=file_path
        self.parent_path=os.path.dirname(self.file_path)
        self.file_name=os.path.basename(self.file_path)
        self.file_name_used_before=''

        self.building=''
        self.specility=''
        self.number=''

        self.rotation=0
        with fitz.open(self.file_path) as doc:
            x0=doc[0].cropbox.x0
            y0=doc[0].cropbox.y0
            x1=doc[0].cropbox.x1
            y1=doc[0].cropbox.y1
            w,h=x1-x0,y1-y0
            if w<h:
                self.rotation=90
        self.is_full=False
        self.renameSignal.connect(self.parent.goto_next)
        self.rotateSignal.connect(self.parent.set_pic)
        self.fullSignal.connect(self.parent.set_pic)

    def rotate_clockwise_90(self):
        self.rotation+=90
        self.rotateSignal.emit()

    def tick_full(self):
        self.is_full = not self.is_full
        self.fullSignal.emit()


    def get_image(self):
        return pdf2image(self.file_path,self.rotation,self.is_full)

    @staticmethod
    def Parse(string):
        array=string.split(' ')  # 参数用空格和不用参数,会有细微的差别,不用参数会忽略开的的空格
        alen=len(array)
        if array[0]=='':
            PdfInfo.current_name[1]=array[1]
            PdfInfo.current_name[2]=array[2]
        else:
            if alen==3:
                PdfInfo.current_name=array
            elif alen==2:
                PdfInfo.current_name[0]=array[0]
                PdfInfo.current_name[2]=array[1]
            elif alen==1:
                PdfInfo.current_name[2]=string
            else:
                return None
        return PdfInfo.current_name

    def rename(self,string):
        # 得到了一个文档名三元祖
        res=PdfInfo.Parse(string)
        if res:
            self.building,self.specility,self.number=res
            # 如果res存在,就拼接一下
            res_txt=''.join(res)
            # 临时存放文件名的变量
            name_new=res_txt+'.pdf'
            # 如果该文件已存在,就在后面加上数字后缀
            if self.file_path.replace('\\','/') != os.path.join(self.parent_path,name_new).replace('\\','/'):
                if os.path.isfile(os.path.join(self.parent_path,name_new)):
                    count=2
                    name_new=f'{res_txt} ({count}).pdf'
                    while os.path.isfile(os.path.join(self.parent_path,name_new)):
                        count+=1
                        name_new=f'{res_txt} ({count}).pdf'
                        self.number=f'{self.number} ({count})'
                self.file_name_used_before=self.file_name
                self.file_name=name_new
                os.rename(self.file_path,os.path.join(self.parent_path,self.file_name))
                self.file_path=os.path.join(self.parent_path,name_new)

            self.renameSignal.emit()


class PdfQueue(QObject):
    initilized=pyqtSignal()
    indexChanged=pyqtSignal()

    def __init__(self,pdffiles,parent):
        QObject.__init__(self)
        self.parent=parent
        self.initilized.connect(self.parent.pdf_queue_init)
        self.indexChanged.connect(self.parent.set_change)

        self.pdfObjects=[PdfInfo(f,self.parent) for f in pdffiles]
        for pdfinfo in self.pdfObjects:
            pdfinfo.renameSignal.connect(self.parent.goto_next)

        self.index=-1

    def has_next(self):
        return self.index+1<len(self.pdfObjects)

    def has_last(self):
        return self.index>0

    def read_next(self):
        if self.has_next():
            self.index+=1
            self.indexChanged.emit()
            return self.pdfObjects[self.index]

    def read_last(self):
        if self.has_last():
            self.index-=1
            self.indexChanged.emit()
            return self.pdfObjects[self.index]

    def read_now(self):
        if self.index>-1:
            return self.pdfObjects[self.index]

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值