如何在python中将文件保存到excel时显示进度条?

如何在python中将文件保存到excel时显示进度条?,python,excel,pyqt,pyqt5,qprogressbar,Python,Excel,Pyqt,Pyqt5,Qprogressbar,如果你能帮助我,我将不胜感激。在将文件保存到excel时,我无法显示进度条。我想要实现的是,在从pandas数据框和qwidgetable保存excel文件时显示进度条,因为保存之前需要时间。在下载或保存excel文件之前,我希望进度条关闭。我试着在网上查找,但我看不到我的问题的具体答案。到目前为止,这是我创建的编译代码 import sys from PyQt5 import QtWidgets, QtCore import pandas as pd import time import ps

如果你能帮助我,我将不胜感激。在将文件保存到excel时,我无法显示进度条。我想要实现的是,在从
pandas数据框
qwidgetable
保存excel文件时显示进度条,因为保存之前需要时间。在下载或保存excel文件之前,我希望进度条关闭。我试着在网上查找,但我看不到我的问题的具体答案。到目前为止,这是我创建的编译代码

import sys
from PyQt5 import QtWidgets, QtCore
import pandas as pd
import time
import psutil


class ThreadClass(QtCore.QThread):
   updateProgressBar = QtCore.pyqtSignal(int)

   def __init__(self, parent=None):
       super(ThreadClass, self).__init__(parent)

   def run(self):
       while True:
           val = int(psutil.cpu_percent())
           time.sleep(1)
           self.updateProgressBar.emit(val)

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        self.setGeometry(50,50,500,500)
        self.setWindowTitle('PyQt Tuts')
        self.table()

    def updateProgressBar(self, val):
        self.progressBar.setValue(val)

    def table(self):
        self.tableWidget = QtWidgets.QTableWidget()
        self.tableWidget.setGeometry(QtCore.QRect(220, 100, 411, 392))
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setRowCount(5)
        self.tableWidget.show()

        item = QtWidgets.QTableWidgetItem()
        item.setText("Amount")
        self.tableWidget.setHorizontalHeaderItem(1, item)

        records = [
            ['Product 1', 1000],
            ['Product 2', 500],
            ['Product 3', 600],
            ['Product 4', 300],
            ['Product 5', 800],
        ]

        self.df = pd.DataFrame(records, columns=['Name', 'Amount'])

        for r in range(5):
            for c in range(2):
                table_item = str(self.df.iloc[r, c])
                self.tableWidget.setItem(r, c, QtWidgets.QTableWidgetItem(table_item))

        self.pb_extract = QtWidgets.QPushButton(self.tableWidget)
        self.pb_extract.setGeometry(QtCore.QRect(10, 200, 75, 23))
        self.pb_extract.clicked.connect(self.extract)
        self.pb_extract.setText("EXTRACT")
        self.pb_extract.show()

    def extract(self):
        self.lb_downloading = QtWidgets.QLabel(self.tableWidget)
        self.lb_downloading.setGeometry(QtCore.QRect(10, 270, 81, 16))
        self.lb_downloading.setText("Downloading..")
        self.lb_downloading.show()

        self.progressBar = QtWidgets.QProgressBar(self.tableWidget)
        self.progressBar.setGeometry(QtCore.QRect(10, 290, 171, 10))
        self.progressBar.show()

        self.threadclass = ThreadClass()
        self.threadclass.start()
        self.threadclass.updateProgressBar.connect(self.updateProgressBar)

        self.df.to_excel('Products.xlsx', index=False)
        print('Download complete!')

def run():
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle("fusion")
    w = Window()
    sys.exit(app.exec_())

run()
这些代码如下所示:

我想要实现的是,当我单击“提取”按钮时,下载进度栏将关闭,直到excel文件完全下载/保存

(另外,我只是得到了
val=int(psutil.cpu_percent())
的随机值,因为我也不知道在应用程序运行时要使用什么特定的代码/函数,只是为了向您显示我的进度条正在移动。)

提前谢谢你

这些类型的问题在SO中被问了无数次,并且在注释中多次解释了要求,解释了在哪种情况下是可能的,在哪种情况下是不可能的。因此,为了避免重复同样的事情,我将根据OP的问题在这篇文章中解释这个主题

小部件通常用于显示和/或从用户处获取信息,QProgressBar做的第一件事是,它显示进度信息,而不是计算进度

如果任务可以细分为“n”个子任务,则可以计算进度,因为相对于总子任务数,它将等于已完成的子任务数

  • 例如,如果任务是将一个N KB的文件上载到服务器,则每个子任务可以包含1KB的信息,因此进度为:

    progress = 100 * number_of_KB_submitted/number_of_KB_of_file
    
  • 另一个例子是,如果您必须复制n个文件,则进度将为:

    progress = 100 * number_of_copied_files / number_of_total_files
    
从上面可以明显看出,只有当任务可以细分为子任务时,才能计算进度,因此,如果任务不能细分,则无法计算任何进度

在将熊猫保存在excel中的情况下,显然不能将其细分为“n”个任务,因此无法计算其进度

在使用to_excel将熊猫保存在excel中的情况下,显然不能将其细分为“n”个任务,因此无法计算其进度

这些情况下的一个解决方法是显示繁忙的QProgressBar:

progressbar.setRange(0, 0)
就你而言:

import sys
from PyQt5 import QtWidgets, QtCore
import pandas as pd
import time

import threading


class ExcelWorker(QtCore.QObject):
    started = QtCore.pyqtSignal()
    finished = QtCore.pyqtSignal()

    def execute(self, df, filename):
        threading.Thread(target=self._execute, args=(df, filename), daemon=True).start()

    def _execute(self, df, filename):
        self.started.emit()
        df.to_excel(filename, index=False)
        self.finished.emit()


class DownloaderProgressBar(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(DownloaderProgressBar, self).__init__(parent)

        self._progressbar = QtWidgets.QProgressBar()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(QtWidgets.QLabel(self.tr("Downloading..")))
        lay.addWidget(self.progressbar)

    @property
    def progressbar(self):
        return self._progressbar


class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        self.setGeometry(50, 50, 500, 500)
        self.setWindowTitle("PyQt Tuts")
        self.create_table()

        self.create_progressbar()
        self.create_worker()

    def create_progressbar(self):
        self.downloader_progressbar = DownloaderProgressBar(self.tableWidget)
        self.downloader_progressbar.setGeometry(10, 270, 170, 80)
        self.downloader_progressbar.hide()

    def create_worker(self):
        self.worker = ExcelWorker()
        self.worker.started.connect(self.on_started)
        self.worker.finished.connect(self.on_finished)

    def create_table(self):
        self.tableWidget = QtWidgets.QTableWidget()
        self.tableWidget.setGeometry(QtCore.QRect(220, 100, 411, 392))
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setRowCount(5)
        self.tableWidget.show()

        item = QtWidgets.QTableWidgetItem()
        item.setText("Amount")
        self.tableWidget.setHorizontalHeaderItem(1, item)

        records = [
            ["Product 1", 1000],
            ["Product 2", 500],
            ["Product 3", 600],
            ["Product 4", 300],
            ["Product 5", 800],
        ]

        self.df = pd.DataFrame(records, columns=["Name", "Amount"])

        for r in range(5):
            for c in range(2):
                table_item = str(self.df.iloc[r, c])
                self.tableWidget.setItem(r, c, QtWidgets.QTableWidgetItem(table_item))

        self.pb_extract = QtWidgets.QPushButton(self.tableWidget)
        self.pb_extract.setGeometry(QtCore.QRect(10, 200, 75, 23))
        self.pb_extract.clicked.connect(self.extract)
        self.pb_extract.setText("EXTRACT")
        self.pb_extract.show()

    def extract(self):
        self.worker.execute(self.df.copy(), "Products.xlsx")
        self.downloader_progressbar.show()

    @QtCore.pyqtSlot()
    def on_started(self):
        self.downloader_progressbar.progressbar.setRange(0, 0)

    @QtCore.pyqtSlot()
    def on_finished(self):
        self.downloader_progressbar.progressbar.setRange(0, 1)


def run():
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle("fusion")
    w = Window()
    sys.exit(app.exec_())


run()

谢谢你,先生!我还不熟悉progressbar,老实说,我是个编程新手。你清楚地解释了它的目的。非常感谢。我只是想知道是否有可能把时间作为进度条?可能吗?“100*时间/总完成时间”?谢谢大家!@AlvinLorejas您知道将pandas转换为excel需要多长时间吗?如果这在转换过程中是已知的,则为是,否则为您的情况:否。