<p>感谢HashSplat的输入。我有一些更新,使其功能齐全:</p>
<pre><code>class FtpWindow(QtGui.QDialog):
def __init__(self, parent=None):
self.fileList = QtGui.QTreeWidget()
self.ftp = QtNetwork.QFtp(self)
self.progressDialog = QtGui.QProgressDialog(self)
self.progressDialog.canceled.connect(self.ftp.abort)
self.downloadAllButton.clicked.connect(self.downloadAllFile)
self.ref_holder = {}
self.ftp.commandFinished.connect(self.ftpCommandFinished)
def download_file(self, fileName):
"""Non blocking start downloading a file."""
self.outFile = QtCore.QFile(fileName)
""" Need this to have files saved locally """
if not self.outFile.open(QtCore.QIODevice.WriteOnly):
QtGui.QMessageBox.information(self, "FTP",
"Unable to save the file %s." % fileName)
self.outFile = None
return
cmd_id = self.ftp.get(filename, self.outFile) # Non blocking just start downloading
# This keeps the object alive and doesn't overwrite them.
self.ref_holder[cmd_id] = [filename, self.outFile]
def downloadAllFile(self):
self.progressDialog.reset()
self.num_downloads = self.fileList.topLevelItemCount()
self.counter=1
self.progressDialog.setLabelText("Downloading %d/%d files ..." % (self.counter, self.num_downloads))
self.progressDialog.show()
for jj in range(num_downloads): # how many files in a particular folder
fileName = self.fileList.topLevelItem(jj).text(0)
self.download_file(fileName) # Non blocking, and doesn't overwrite self.outFile with every iteration
def ftpCommandFinished(self, cmd_id, error=None):
"""Increased the number of items finished."""
self.progressDialog.setValue(self.progressDialog.value()+1)
item = self.ref_holder.pop(cmd_id) # Remove the reference for the finished item
if error:
self.progressDialog.setLabelText("Error downloading %s" % item[0])
# Check if all downloads are done
if len(self.ref_holder) == 0:
self.progressDialog.close() # This closes the extra window
self.outFile.close() # You need this to have the last file saved
else:
self.counter+=1
self.progressDialog.setLabelText("Downloading %d/%d files ..." % (self.counter, self.num_downloads))
def updateDataTransferProgress(self, readBytes, totalBytes):
self.progressDialog.setMaximum(totalBytes)
self.progressDialog.setValue(readBytes)
</code></pre>