将进度条添加到PyQt5中的方法

问题描述 投票:2回答:1

我在这里有一个简单的PyQt5应用程序,可以从Pdf转换为excel。当我单击按钮进行转换时,我想在下面的方法转换中添加一个进度条,因为它需要一段时间才能执行,因此有一些可视化效果会很棒。

这是我的代码如下:

我从Qtdesigner加载ui。此外,我可以添加一个可以附加到pushButton_3的进度条。进度条可以称为“ProgressBar”。请让我知道如何完成它,因为这里的大部分答案并没有真正回答这个问题。


import sys
from PyQt5.QtWidgets import QMainWindow,QApplication,QTableView, QWidget, QFileDialog,QPushButton,QVBoxLayout,QMessageBox
from PyQt5 import uic
from PyPDF2 import PdfFileReader
from PyQt5 import QtCore,QtGui
import pandas as pd
import tabula
import re
from PandasModel import PandasModel

class App(QMainWindow):

    def __init__(self):
        QWidget.__init__(self)
        uic.loadUi('designUI.ui',self)
        self.pushButton.clicked.connect(self.openFileNameDialog)
        self.pushButton_3.clicked.connect(self.convert)
        self.pushButton_2.clicked.connect(self.view)
        self.pushButton_4.clicked.connect(self.saveFileDialog)

    def openFileNameDialog(self):    
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self,"Open File", "","All Files (*);;Python Files (*.py)")#, options=options)
        if fileName:
            self.file=fileName

    def view(self):
        model=PandasModel(self.converted_file)
        self.tableView.setModel(model)

    def convert(self):
        self.converted_file=self.pdf2excel(self.file)

    def saveFileDialog(self):    
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getSaveFileName(self, 'Save File', '', ".xls(*.xls)")
        if fileName:
            self.converted_file.to_excel(fileName)
            msg=QMessageBox()
            msg.setText('File is Saved')
            msg.setStandardButtons(QMessageBox.Ok)
            #msg.buttonClicked.connect(msgbtn) 
            msg.exec_()

    def pdf2excel(self,pdf_file):    
        pdf = PdfFileReader(open(pdf_file,'rb'))
        length=pdf.getNumPages()        
        result=pd.DataFrame(columns=['Department','Employment No','Employment Name',"Hire Date","Term Date","Birth Date",
         "Seniority Date","Pay Code","FT/PT/S","Status"])        
        page=1
        while page <= length:
            df=tabula.read_pdf(pdf_file, pages = str(page),lattice =True, area=(75.775,16.0,572.715,779.29))[1:]
            pattern = re.compile(r'(\s){2,}')
            df=pd.DataFrame(df[df.columns[0]].replace(pattern,","))
            df=df['Unnamed: 0'].str.split(",",expand=True)
            df=df.rename(columns={0:'Department',
              1:'Employment No',2:'Employment Name',3:"Hire Date",4:"Term Date",5:"Birth Date",
              6:"Seniority Date",7:"Pay Code",8:"FT/PT/S",9:"Status"})
            result=result.append(df,ignore_index=True)
            page+=1
        result["Hire Date"]=pd.to_datetime(result["Hire Date"])
        result["Term Date"]=pd.to_datetime(result["Term Date"])
        result["Days Difference"]=(result['Term Date']-result['Hire Date']).dt.days
        result=result.dropna(how='all')
        result=result.drop(columns=['Birth Date','Pay Code','Status'])
        result=result[['Department','Employment No','Employment Name',"Hire Date","Term Date","Days Difference",
         "Seniority Date","FT/PT/S"]]
        return result

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setWindowIcon(QtGui.QIcon('pdf-to-excel-icon.png'))
    ex = App()
    ex.show()
    sys.exit(app.exec_())  

python pyqt pyqt5 qprogressbar
1个回答
2
投票

首先,我建议进行变量存在或具有一定大小的验证,例如在尝试将代码与任何pdf一起使用时,代码就会被破坏。

回答这个问题,当您运行pdf2excel时,您将看到无法更改窗口的大小,因为GUI已冻结,因此它必须在另一个线程上运行,并通过信号将信息作为进度和数据帧发送。在这种情况下,我将创建一个工作者(QObject),它将存在于具有pdf2excel函数的另一个线程中。

import sys
from functools import partial
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyPDF2 import PdfFileReader
import pandas as pd
import tabula
import re
from PandasModel import PandasModel


class PdfObject(QtCore.QObject):
    progressChanged = QtCore.pyqtSignal(int)
    maximumChanged = QtCore.pyqtSignal(int)
    pandasChanged = QtCore.pyqtSignal(pd.DataFrame)

    @QtCore.pyqtSlot(str)
    def pdf2excel(self, pdf_file):
        pdf = PdfFileReader(open(pdf_file, "rb"))
        length = pdf.getNumPages()
        result = pd.DataFrame(
            columns=[
                "Department",
                "Employment No",
                "Employment Name",
                "Hire Date",
                "Term Date",
                "Birth Date",
                "Seniority Date",
                "Pay Code",
                "FT/PT/S",
                "Status",
            ]
        )
        self.maximumChanged.emit(length)
        page = 1
        while page <= length:
            self.progressChanged.emit(page)
            df = tabula.read_pdf(
                pdf_file,
                pages=str(page),
                lattice=True,
                area=(75.775, 16.0, 572.715, 779.29),
            )[1:]
            pattern = re.compile(r"(\s){2,}")
            df = pd.DataFrame(df[df.columns[0]].replace(pattern, ","))
            df = df["Unnamed: 0"].str.split(",", expand=True)
            df = df.rename(
                columns={
                    0: "Department",
                    1: "Employment No",
                    2: "Employment Name",
                    3: "Hire Date",
                    4: "Term Date",
                    5: "Birth Date",
                    6: "Seniority Date",
                    7: "Pay Code",
                    8: "FT/PT/S",
                    9: "Status",
                }
            )
            result = result.append(df, ignore_index=True)
            page += 1
        result["Hire Date"] = pd.to_datetime(result["Hire Date"])
        result["Term Date"] = pd.to_datetime(result["Term Date"])
        result["Days Difference"] = (
            result["Term Date"] - result["Hire Date"]
        ).dt.days
        result = result.dropna(how="all")
        result = result.drop(columns=["Birth Date", "Pay Code", "Status"])
        result = result[
            [
                "Department",
                "Employment No",
                "Employment Name",
                "Hire Date",
                "Term Date",
                "Days Difference",
                "Seniority Date",
                "FT/PT/S",
            ]
        ]
        self.pandasChanged.emit(result)


class App(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)
        uic.loadUi("designUI.ui", self)

        self.filename = ""
        self.converted_file = None

        thread = QtCore.QThread(self)
        thread.start()
        self.pdf_object = PdfObject()
        self.pdf_object.moveToThread(thread)
        self.pdf_object.maximumChanged.connect(self.progressBar.setMaximum)
        self.pdf_object.progressChanged.connect(self.progressBar.setValue)
        self.pdf_object.pandasChanged.connect(self.on_pandasChanged)

        self.pushButton.clicked.connect(self.openFileNameDialog)
        self.pushButton_3.clicked.connect(self.convert)
        self.pushButton_2.clicked.connect(self.view)
        self.pushButton_4.clicked.connect(self.saveFileDialog)

    def openFileNameDialog(self):
        options = QtWidgets.QFileDialog.Options()
        options |= QtWidgets.QFileDialog.DontUseNativeDialog
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(
            self, "Open File", "", "All Files (*);;Python Files (*.py)"
        )  # , options=options)
        if fileName:
            self.filename = fileName

    def view(self):
        if self.converted_file is not None:
            model = PandasModel(self.converted_file)
            self.tableView.setModel(model)

    def convert(self):
        if self.filename:
            wrapper = partial(self.pdf_object.pdf2excel, self.filename)
            QtCore.QTimer.singleShot(0, wrapper)

    @QtCore.pyqtSlot(pd.DataFrame)
    def on_pandasChanged(self, df):
        self.converted_file = df.copy()

    def saveFileDialog(self):
        options = QtWidgets.QFileDialog.Options()
        options |= QtWidgets.QFileDialog.DontUseNativeDialog
        fileName, _ = QtWidgets.QFileDialog.getSaveFileName(
            self, "Save File", "", ".xls(*.xls)"
        )
        if fileName and self.converted_file is not None:
            self.converted_file.to_excel(fileName)
            msg = QtWidgets.QMessageBox()
            msg.setText("File is Saved")
            msg.setStandardButtons(QtWidgets.QMessageBox.Ok)
            # msg.buttonClicked.connect(msgbtn)
            msg.exec_()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    app.setWindowIcon(QtGui.QIcon("pdf-to-excel-icon.png"))
    ex = App()
    ex.show()
    sys.exit(app.exec_())
© www.soinside.com 2019 - 2024. All rights reserved.