gpt4 book ai didi

python - 作业完成之前进度条不会呈现

转载 作者:行者123 更新时间:2023-12-01 01:21:45 25 4
gpt4 key购买 nike

我正在尝试制作一个复制大文件的进度条。但是,当前对话框窗口会变黑,直到该过程完成。我现在明白我可能必须学习如何使用步骤并将数据传递回 GUI。但我仍然不明白为什么窗口无法完全渲染。我知道窗口是否因为 moveFilesWithProgress 函数正在运行而无响应。但在该函数中我正在更新进度条值。我什至尝试添加 QtGui.QGuiApplication.processEvents() 希望它能在继续迭代之前更新 gui。

我将不胜感激任何可能在没有多线程进程的情况下解决这个问题的帮助,但如果不可能,我将非常感谢一个如何使用 Qthread 的简单示例。我发现了一个相关的问题,但我需要做很多事情才能理解这个例子。 here is the link

示例代码:

#!/usr/bin/env python
import os
import sys
import shutil
from PyQt5.QtWidgets import (QApplication, QDialog, QLineEdit, QMainWindow,
QPushButton, QProgressBar)
import PyQt5.QtGui as QtGui

class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.button = QPushButton("Copy", self)
self.button.clicked.connect(self.archiveEntry)
self.show()

def archiveEntry(self):
self.p = ProgressBar()
self.p.show()
Dir = "/media/zachlab/Windows/LinuxStorage/old/embryos"
outDir = "/media/zachlab/Windows/LinuxStorage/old/out"
run = self.p.moveFilesWithProgress(Dir, outDir)
# if run:
# self.p.close


class ProgressBar(QDialog):
def __init__(self):
super().__init__()
self.pbar = QProgressBar(self)

def timerEvent(self, e):
if self.step >= 100:
self.timer.stop()
self.btn.setText('Finished')
return
self.pbar.setValue(self.step)

def update(self, value):
self.pbar.setValue(value)
QtGui.QGuiApplication.processEvents()

def calculateAndUpdate(self, done, total):
progress = int(round((done / float(total)) * 100))
self.update(progress)


def countFiles(self, directory):
files = []
if os.path.isdir(directory):
for path, dirs, filenames in os.walk(directory):
files.extend(filenames)
return len(files)

def makedirs(self, dest):
if not os.path.exists(dest):
os.makedirs(dest)

def moveFilesWithProgress(self, src, dest):
numFiles = self.countFiles(src)
if os.path.exists(dest):
return 0
if numFiles > 0:
self.makedirs(dest)
numCopied = 0

for path, dirs, filenames in os.walk(src):
for directory in dirs:
destDir = path.replace(src, dest)
self.makedirs(os.path.join(destDir, directory))

for sfile in filenames:
srcFile = os.path.join(path, sfile)
destFile = os.path.join(path.replace(src, dest), sfile)
shutil.copy(srcFile, destFile)
numCopied += 1
self.calculateAndUpdate(numCopied, numFiles)
self.show()
return 1
else:
return 0


if __name__ == "__main__":
app = QApplication(sys.argv)
ex = MainWindow()
sys.exit(app.exec_())

最佳答案

繁重的任务不应该在主线程上运行,你应该使用线程。在这种情况下,我已经替换了您的逻辑,因此有一个类负责复制通过进度、错误等迹象通知的文件。该类的对象将存在于另一个线程中,通过信号通知 GUI,在此案例我将使用 QProgressDialog 来显示进度。

#!/usr/bin/env python
import os
import sys
import shutil
import threading
from PyQt5 import QtCore, QtGui, QtWidgets

class MainWindow(QtWidgets.QMainWindow):
startMoveFilesSignal = QtCore.pyqtSignal(str, str)

def __init__(self):
super(MainWindow, self).__init__()
srcdir = "/media/zachlab/Windows/LinuxStorage/old/embryos"
dstdir = "/media/zachlab/Windows/LinuxStorage/old/out"
self.le_src = QtWidgets.QLineEdit(srcdir)
self.le_dst = QtWidgets.QLineEdit(dstdir)
self.button = QtWidgets.QPushButton("Copy")
self.button.clicked.connect(self.archiveEntry)

central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QFormLayout(central_widget)
lay.addRow("From: ", self.le_src)
lay.addRow("To: ", self.le_dst)
lay.addRow(self.button)

self.progressbar = QtWidgets.QProgressDialog(self)
self.progressbar.hide()

thread = QtCore.QThread(self)
thread.start()
self.helper = MoveFileHelper()
self.startMoveFilesSignal.connect(self.helper.moveFilesWithProgress)
self.helper.progressChanged.connect(self.progressbar.setValue)
self.helper.finished.connect(self.on_finished)
self.helper.started.connect(self.progressbar.show)
self.helper.errorOccurred.connect(self.on_errorOcurred)
self.helper.moveToThread(thread)

@QtCore.pyqtSlot()
def archiveEntry(self):
self.startMoveFilesSignal.emit(self.le_src.text(), self.le_dst.text())
self.progressbar.hide()

@QtCore.pyqtSlot()
def on_finished(self):
self.button.setText('Finished')

@QtCore.pyqtSlot(str)
def on_errorOcurred(self, msg):
QtWidgets.QMessageBox.critical(self, "Error Ocurred", msg)

class MoveFileHelper(QtCore.QObject):
progressChanged = QtCore.pyqtSignal(int)
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
errorOccurred = QtCore.pyqtSignal(str)

def calculateAndUpdate(self, done, total):
progress = int(round((done / float(total)) * 100))
self.progressChanged.emit(progress)

@staticmethod
def countFiles(directory):
count = 0
if os.path.isdir(directory):
for path, dirs, filenames in os.walk(directory):
count += len(filenames)
return count

@staticmethod
def makedirs(dest):
if not os.path.exists(dest):
os.makedirs(dest)

@QtCore.pyqtSlot(str, str)
def moveFilesWithProgress(self, src, dest):
numFiles = MoveFileHelper.countFiles(src)
if os.path.exists(dest):
self.errorOccurred.emit("Dest exist")
return
if numFiles > 0:
self.started.emit()
MoveFileHelper.makedirs(dest)
numCopied = 0
for path, dirs, filenames in os.walk(src):
for directory in dirs:
destDir = path.replace(src, dest)
MoveFileHelper.makedirs(os.path.join(destDir, directory))

for sfile in filenames:
srcFile = os.path.join(path, sfile)
destFile = os.path.join(path.replace(src, dest), sfile)
shutil.copy(srcFile, destFile)
numCopied += 1
self.calculateAndUpdate(numCopied, numFiles)
self.finished.emit()

if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = MainWindow()
ex.resize(640, ex.sizeHint().height())
ex.show()
sys.exit(app.exec_())

关于python - 作业完成之前进度条不会呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53751909/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com