PyQt文件复制进度条

发布于 2024-10-27 09:27:04 字数 1759 浏览 0 评论 0原文

我正在尝试获取 QProgressBar 来显示 PyQt 中文件复制的进度。我已经查看过并且已经使用 QFile 在线程中运行实际副本。我只是无法让栏更新。

这是一些代码:

class ProgressDialog(QtGui.QDialog):

    def __init__(self, parent, source, destination):
        QtGui.QDialog.__init__(self, parent)
        self.parent = parent
        self.source = source
        self.destination = destination

        self.add_diag = progress_diag.Ui_Dialog()
        self.add_diag.setupUi(self)

        self.add_diag.infoLabel.setText("Copying: %s" % (self.source))
        self.sourcefile = QtCore.QFile(self.source)

        self.add_diag.progressBar.setMinimum(0)
        self.add_diag.progressBar.setMaximum(self.sourcefile.size()/1024)

        self.written = 0

        self.show()
        self.copy()

    def copy(self):

        copy_thread = CopyThread(self, self.sourcefile, self.destination)
        self.connect(copy_thread.destination_file, QtCore.SIGNAL("bytesWritten(qint64)"), self.update_progress)
        copy_thread.procDone.connect(self.finished_copy)
        copy_thread.start()

    def update_progress(self, progress):
        print "Working", progress
        self.written += progress
        self.add_diag.progressBar.setValue(written/1024)

    def finished_copy(self, state):
        self.close()

class CopyThread(QtCore.QThread):

    procDone = QtCore.pyqtSignal(bool)

    def __init__(self, parent, source, destination):
        QtCore.QThread.__init__(self, parent)
        self.source = source
        self.destination_file = QtCore.QFile(destination)

    def run(self):
        self.source.copy(self.destination_file.fileName())
        self.procDone.emit(True)

update_progess 永远不会被调用,因此信号显然没有被发出,但我不确定为什么。

我对此进行了大量搜索,但还没有找到一个好的 PyQt 解决方案,所以任何帮助都会很棒。

I am trying to get a QProgressBar to show the progress of a file copy in PyQt. I've looked about and I've got as far as running the actual copy in a thread using QFile. I just can't get the bar to update though.

Here's some code:

class ProgressDialog(QtGui.QDialog):

    def __init__(self, parent, source, destination):
        QtGui.QDialog.__init__(self, parent)
        self.parent = parent
        self.source = source
        self.destination = destination

        self.add_diag = progress_diag.Ui_Dialog()
        self.add_diag.setupUi(self)

        self.add_diag.infoLabel.setText("Copying: %s" % (self.source))
        self.sourcefile = QtCore.QFile(self.source)

        self.add_diag.progressBar.setMinimum(0)
        self.add_diag.progressBar.setMaximum(self.sourcefile.size()/1024)

        self.written = 0

        self.show()
        self.copy()

    def copy(self):

        copy_thread = CopyThread(self, self.sourcefile, self.destination)
        self.connect(copy_thread.destination_file, QtCore.SIGNAL("bytesWritten(qint64)"), self.update_progress)
        copy_thread.procDone.connect(self.finished_copy)
        copy_thread.start()

    def update_progress(self, progress):
        print "Working", progress
        self.written += progress
        self.add_diag.progressBar.setValue(written/1024)

    def finished_copy(self, state):
        self.close()

class CopyThread(QtCore.QThread):

    procDone = QtCore.pyqtSignal(bool)

    def __init__(self, parent, source, destination):
        QtCore.QThread.__init__(self, parent)
        self.source = source
        self.destination_file = QtCore.QFile(destination)

    def run(self):
        self.source.copy(self.destination_file.fileName())
        self.procDone.emit(True)

update_progess never gets called so the signal obviously isn't being emitted but I'm not sure why.

I've searched high and low on this but haven't found a good PyQt solution for this so any help would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝天白云 2024-11-03 09:27:04

好的,这就是我想出的方法,它有效,但显然会降低文件复制性能。

class ProgressDialog(QtGui.QDialog):

    def __init__(self, parent, source, destination):
        QtGui.QDialog.__init__(self, parent)
        self.parent = parent
        self.source = source
        self.destination = destination
        self.add_diag = progress_diag.Ui_Dialog()
        self.add_diag.setupUi(self)

        self.add_diag.infoLabel.setText("Copying: %s" % (self.source))

        self.add_diag.progressBar.setMinimum(0)
        self.add_diag.progressBar.setMaximum(100)
        self.add_diag.progressBar.setValue(0)

        self.show()
        self.copy()

    def copy(self):

        copy_thread = CopyThread(self, self.source, self.destination)
        copy_thread.procPartDone.connect(self.update_progress)
        copy_thread.procDone.connect(self.finished_copy)
        copy_thread.start()

    def update_progress(self, progress):
        self.add_diag.progressBar.setValue(progress)

    def finished_copy(self, state):
        self.close()

class CopyThread(QtCore.QThread):

    procDone = QtCore.pyqtSignal(bool)
    procPartDone = QtCore.pyqtSignal(int)

    def __init__(self, parent, source, destination):
        QtCore.QThread.__init__(self, parent)
        self.source = source
        self.destination = destination

    def run(self):
        self.copy()
        self.procDone.emit(True)

    def copy(self):
        source_size = os.stat(self.source).st_size
        copied = 0
        source = open(self.source, "rb")
        target = open(self.destination, "wb")

        while True:
            chunk = source.read(1024)
            if not chunk:
                break
            target.write(chunk)
            copied += len(chunk)
            self.procPartDone.emit(copied * 100 / source_size)

        source.close()
        target.close()

Ok so here's what I came up with which works but obviously slows down the file copy performance.

class ProgressDialog(QtGui.QDialog):

    def __init__(self, parent, source, destination):
        QtGui.QDialog.__init__(self, parent)
        self.parent = parent
        self.source = source
        self.destination = destination
        self.add_diag = progress_diag.Ui_Dialog()
        self.add_diag.setupUi(self)

        self.add_diag.infoLabel.setText("Copying: %s" % (self.source))

        self.add_diag.progressBar.setMinimum(0)
        self.add_diag.progressBar.setMaximum(100)
        self.add_diag.progressBar.setValue(0)

        self.show()
        self.copy()

    def copy(self):

        copy_thread = CopyThread(self, self.source, self.destination)
        copy_thread.procPartDone.connect(self.update_progress)
        copy_thread.procDone.connect(self.finished_copy)
        copy_thread.start()

    def update_progress(self, progress):
        self.add_diag.progressBar.setValue(progress)

    def finished_copy(self, state):
        self.close()

class CopyThread(QtCore.QThread):

    procDone = QtCore.pyqtSignal(bool)
    procPartDone = QtCore.pyqtSignal(int)

    def __init__(self, parent, source, destination):
        QtCore.QThread.__init__(self, parent)
        self.source = source
        self.destination = destination

    def run(self):
        self.copy()
        self.procDone.emit(True)

    def copy(self):
        source_size = os.stat(self.source).st_size
        copied = 0
        source = open(self.source, "rb")
        target = open(self.destination, "wb")

        while True:
            chunk = source.read(1024)
            if not chunk:
                break
            target.write(chunk)
            copied += len(chunk)
            self.procPartDone.emit(copied * 100 / source_size)

        source.close()
        target.close()
舂唻埖巳落 2024-11-03 09:27:04

QFile 不发出 bytesWritten:

与其他 QIODevice 不同
实现,例如 QTcpSocket,
QFile 不发出
aboutToClose()、bytesWritten() 或
readRead() 信号。这
实现细节意味着 QFile
不适合阅读和
写入某些类型的文件,例如
作为 Unix 平台上的设备文件。

http://doc.qt.nokia.com/latest/qfile.html

您必须实现自己的循环并自己发出进度。

QFile does not emit bytesWritten:

Unlike other QIODevice
implementations, such as QTcpSocket,
QFile does not emit the
aboutToClose(), bytesWritten(), or
readyRead() signals. This
implementation detail means that QFile
is not suitable for reading and
writing certain types of files, such
as device files on Unix platforms.

http://doc.qt.nokia.com/latest/qfile.html

You will have to implement your own loop and emit the progress yourself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文