問(wèn)題描述
如果你能幫助我,不勝感激.將文件保存到 Excel 時(shí),我無(wú)法顯示進(jìn)度條.我想要實(shí)現(xiàn)的是顯示進(jìn)度條,同時(shí)從 pandas dataframe
也從 qwidgettable
保存 excel 文件,因?yàn)樗枰獣r(shí)間才能保存.在下載或保存 excel 文件之前,我希望該進(jìn)度條關(guān)閉.我試著在網(wǎng)上查看,但我看不到我的查詢的具體答案.到目前為止,這是我創(chuàng)建的編譯代碼.
Appreciate if you could help me. I have a trouble showing up the progress bar while saving file to excel. What I want to achieve is to show a progress bar while saving excel file from a pandas dataframe
also from qwidgettable
as it takes time before it saves. Until the excel file is downloaded or saved i want that progress bar to close. I tried looking over the net but I cant see specific answers to my query. So far, this is the compiled codes I have created.
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()
這些代碼如下所示:
我想要實(shí)現(xiàn)的是當(dāng)我單擊提取按鈕時(shí),下載進(jìn)度條將關(guān)閉,直到 excel 文件完全下載/保存.
what i want to achieve is when i click the extract button, the downloading progressbar will close until the excel file fully downloaded/saved.
(PS 我只是得到 val = int(psutil.cpu_percent())
的隨機(jī)值,因?yàn)槲乙膊恢涝趹?yīng)用程序運(yùn)行時(shí)使用什么特定代碼/函數(shù)只是為了顯示告訴你我有一個(gè)進(jìn)度條在移動(dòng).)
(P.S i just get random values for val = int(psutil.cpu_percent())
because i also don't know what specific code/function to use while the app is running just to show to you that i have a progress bar moving.)
提前謝謝你!
推薦答案
這類(lèi)問(wèn)題在SO里被問(wèn)過(guò)無(wú)數(shù)次了,而且很多時(shí)候在評(píng)論里解釋過(guò)需求說(shuō)明什么情況下才有可能,在哪些情況下是不可能的.所以為了避免重復(fù)同樣的事情,我將根據(jù)OP的問(wèn)題在這篇文章中解釋這個(gè)主題.
一個(gè)小部件通常用于顯示和/或從用戶那里獲取信息,QProgressBar 做第一件事,也就是說(shuō),它顯示進(jìn)度信息,它不計(jì)算一下.
A widget in general is used to show and/or obtain information from the user, and a QProgressBar does the first thing, that is, it shows the progress information, it does not calculate it.
如果可以將任務(wù)細(xì)分為n"個(gè)子任務(wù),則可以計(jì)算進(jìn)度,因?yàn)樗喈?dāng)于已經(jīng)完成的子任務(wù)數(shù)相對(duì)于總子任務(wù)數(shù).
Progress can be calculated if the task can be subdivided into "n" subtasks, since it would be equivalent to the number of subtasks already done with respect to the number of total subtasks.
比如任務(wù)是上傳一個(gè)N KB的文件到服務(wù)器,那么每個(gè)子任務(wù)可以有1KB的信息,所以進(jìn)度是:
For example if the task is to upload a N KB file to a server, then each subtask can be 1KB of information, so the progress would be:
progress = 100 * number_of_KB_submitted/number_of_KB_of_file
另一個(gè)例子是如果你必須復(fù)制 n 個(gè)文件,那么進(jìn)度是:
Another example would be if you have to copy n files, then the progress would be:
progress = 100 * number_of_copied_files / number_of_total_files
從上面可以看出,只有任務(wù)可以細(xì)分為子任務(wù),才能計(jì)算進(jìn)度,所以如果任務(wù)不能細(xì)分,就不可能計(jì)算任何進(jìn)度.
From the above it is obvious that progress can only be calculated if the task can be subdivided into subtasks, so if the task cannot be subdivided then it is impossible to calculate any progress.
在將 pandas 保存在 excel 中的情況下,很明顯它不能細(xì)分為n"個(gè)任務(wù),因此無(wú)法計(jì)算其進(jìn)度.
In the case of saving the pandas in an excel it is obvious that it cannot be subdivided into "n" tasks so it will be impossible to calculate its progress.
在使用 to_excel 將 pandas 保存在 excel 中的情況下,很明顯它不能細(xì)分為n"個(gè)任務(wù),因此無(wú)法計(jì)算其進(jìn)度.
In the case of saving the pandas in an excel using to_excel it is obvious that it cannot be subdivided into "n" tasks so it will be impossible to calculate its progress.
在這些情況下的解決方法是顯示繁忙的 QProgressBar:
A workaround in those cases is to show a busy 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()
這篇關(guān)于如何在python中將文件保存為excel時(shí)顯示進(jìn)度條?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!