I am trying to download multiple files from a ftp site using a for-loop. The following code seems to work only for the first 2 files in the loop before the python.exe shutdown window pops up. Two downloaded files are perfect, but the 3rd downloaded file is empty upon the shutdown. I don't get the rest of files. Any idea what could be the problem?
from PyQt4 import QtCore, QtGui, QtNetwork
class FtpWindow(QtGui.QDialog):
def __init__(self, parent=None):
self.fileList = QtGui.QTreeWidget()
self.ftp = QtNetwork.QFtp(self)
self.progressDialog = QtGui.QProgressDialog(self)
self.downloadAllButton.clicked.connect(self.downloadAllFile)
self.ftp.commandFinished.connect(self.ftpCommandFinished)
def downloadAllFile(self):
for jj in range(self.fileList.topLevelItemCount()): # how many files in a particular folder
fileName = self.fileList.topLevelItem(jj).text(0)
self.outFile = QtCore.QFile(fileName)
self.ftp.get(fileName, self.outFile) #download one file at a time
self.progressDialog.setLabelText("Downloading %s..." % fileName)
self.progressDialog.exec_()
def ftpCommandFinished(self, _, error):
self.setCursor(QtCore.Qt.ArrowCursor)
if self.ftp.currentCommand() == QtNetwork.QFtp.Get:
if error:
self.statusLabel.setText("Canceled download of %s." % self.outFile.fileName())
self.outFile.close()
self.outFile.remove()
else:
self.statusLabel.setText("Downloaded %s to current directory." % self.outFile.fileName())
self.outFile.close()
self.outFile = None
self.enableDownloadButton()
self.progressDialog.hide()
self.progressDialog.exec_()should be a blocking modal dialog. Useself.progressDialog.show()for a non blocking call.It looks like the ftp get is non blocking so you have to wait until downloading is finished using the commandFinished() signal.
My guess is that every iteration in the loop is overwriting the self.outFile, so there isn't any python references to the object. This makes the object die whenever python does garbage collection. My guess is that your first two files where small and quick and your third file was larger, so the other files were able to download before garbage collection. Either that or garbage collection was just quicker for the last file.
http://pyside.github.io/docs/pyside/PySide/QtNetwork/QFtp.html#PySide.QtNetwork.PySide.QtNetwork.QFtp.get
My example above will hold the filename and outFile object reference until the command is finished. When the command is finished the reference is removed allowing python to clean up the object.