开发者

PyQt file copy progress bar

开发者 https://www.devze.com 2023-02-20 04:47 出处:网络
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

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
        sel开发者_Python百科f.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.


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()


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消