<p><code>self.progressDialog.exec_()</code>应该是一个阻塞模式对话框。对非阻塞调用使用<code>self.progressDialog.show()</code>。你知道吗</p>
<p>看起来ftp get是非阻塞的,所以您必须使用commandFinished()信号等待下载完成。你知道吗</p>
<p>我猜循环中的每个迭代都会覆盖自输出文件,因此没有任何python对该对象的引用。这使得每当python执行垃圾收集时,对象都会死亡。我的猜测是,你的前两个文件小而快,你的第三个文件更大,所以其他文件可以在垃圾收集前下载。对于最后一个文件来说,这或垃圾收集都只是更快。你知道吗</p>
<p><a href="http://pyside.github.io/docs/pyside/PySide/QtNetwork/QFtp.html#PySide.QtNetwork.PySide.QtNetwork.QFtp.get" rel="nofollow noreferrer">http://pyside.github.io/docs/pyside/PySide/QtNetwork/QFtp.html#PySide.QtNetwork.PySide.QtNetwork.QFtp.get</a></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."""
outFile = QtCore.QFile(filename)
cmd_id = self.ftp.get(filename, outFile) # Non blocking just start downloading
# This keeps the object alive and doesn't overwrite them.
self.ref_holder[cmd_id] = [filename, outFile]
def downloadAllFile(self):
self.progressDialog.reset()
num_downloads = self.fileList.topLevelItemCount()
self.progressDialog.setMaximum(num_downloads)
self.progressDialog.setValue(0)
self.progressDialog.setLabelText("Downloading %d files ..." % 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.setValue(self.progressDialog.maximium())
self.progressDialog.close() # This shouldn't be needed
</code></pre>
<p>上面的示例将保留filename和outFile对象引用,直到命令完成。命令完成后,引用将被删除,从而允许python清理对象。你知道吗</p>