簡體   English   中英

如何在 python 中將文件保存到 excel 時顯示進度條?

[英]How to show progress bar while saving file to excel in python?

感謝您能幫助我。 將文件保存到 excel 時無法顯示進度條。 我想要實現的是在從pandas dataframe qwidgettable保存 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 文件完全下載/保存。

(PS 我只是得到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

從上面可以看出,只有任務可以細分為子任務,才能計算進度,所以如果任務不能細分,就不可能計算任何進度。

在將 pandas 保存在 excel 中的情況下,顯然不能將其細分為“n”個任務,因此無法計算其進度。

在使用 to_excel 將 pandas 保存在 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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM