import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QFileDialog, QProgressDialog, QWidget
from PyQt5.QtCore import pyqtSignal, QObject, QThread
from openpyxl import load_workbook, Workbook
class ExcelMerger(QObject):
progressChanged = pyqtSignal(int)
mergeFinished = pyqtSignal()
def merge_excel(self, files, progress_callback):
wb_combined = Workbook()
ws_combined = wb_combined.active
for index, filename in enumerate(files, 1):
progress = int((index / len(files)) * 100)
progress_callback.emit(progress)
wb = load_workbook(filename, read_only=False)
ws = wb.active
for row in ws.iter_rows(values_only=True):
ws_combined.append(row)
wb_combined.save("merged_file.xlsx")
self.mergeFinished.emit()
class MergeThread(QThread):
def __init__(self, files, excel_merger, progress_callback):
super().__init__()
self.files = files
self.excel_merger = excel_merger
self.progress_callback = progress_callback
def run(self):
self.excel_merger.merge_excel(self.files, self.progress_callback)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
self.excel_merger = ExcelMerger()
self.excel_merger.progressChanged.connect(self.on_progress_changed)
self.excel_merger.mergeFinished.connect(self.on_merge_finished)
def initUI(self):
self.setWindowTitle('Excel Merger')
self.setGeometry(100, 100, 300, 200)
layout = QVBoxLayout()
self.merge_btn = QPushButton('Merge Excel Files', self)
self.merge_btn.clicked.connect(self.merge_files)
layout.addWidget(self.merge_btn)
self.widget = QWidget()
self.widget.setLayout(layout)
self.setCentralWidget(self.widget)
def merge_files(self):
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
files, _ = QFileDialog.getOpenFileNames(self, "Select Excel files to merge", "", "Excel Files (*.xlsx *.xls)", options=options)
if files:
self.progress = QProgressDialog(self)
self.progress.setLabelText("Merging files...")
self.progress.setCancelButton(None)
self.progress.setRange(0, 100)
self.progress.show()
self.thread = MergeThread(files, self.excel_merger, self.excel_merger.progressChanged)
self.thread.start()
def on_progress_changed(self, value):
self.progress.setValue(value)
def on_merge_finished(self):
self.progress.close()
print("Files merged successfully.")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
我尝试分离合并线程并设置主窗口,然后运行应用程序的事件循环。但是在文件合并完全完成之前进度条停止。
在这个PyQt5代码中,我试图合并多个Excel文件。文件正在正确合并,但显示上传文件百分比的进度条在所有文件合并之前关闭。我不明白为什么会这样
1条答案
按热度按时间7jmck4yq1#
为什么进度对话框会提前停止,是因为默认情况下,一旦达到最大值,它会立即自动重置,这也会自动关闭对话框。因此,解决问题的最简单方法是进行以下更改:
但是,您当前的代码也比实际需要的要复杂得多,并且每次开始合并时都不必要地创建一个新对话框和一个新线程。因此,我在下面提供了一个简化版本的例子。希望我所做的改变是不言自明的: