2012-11-20 41 views
1

我需要下載ftp目錄中的所有文件。我在程序啓動時不知道目錄中的文件,因此我希望程序列出目錄的內容,然後下載它找到的每個文件。PyQt線程ftp:無法排隊'QUrlInfo'類型的參數

我已經做了一個小演示腳本,從ftp下載文件&在更新進度條的同時這樣做。下載&更新進度欄工作正常,但是,我試圖做的下一步是列出一些目錄的內容&下載文件,並且該部分不起作用。

目前,我只是試圖在任何目錄上做一個列表&將結果打印到命令行。

當我嘗試做一個listInfo.connect,我得到一個錯誤信息:

的QObject ::連接:無法排隊類型「QUrlInfo」 (確保「QUrlInfo」的論點是使用qRegisterMetaType(註冊資本) )

......據我所知,qRegisterMetaType是不是可以在PyQt &做的事情也是一個基本問題的跡象,這裏是我的問題。我可以做一個commandFinished.connect和dataTransferProgress.connect沒有問題,但listInfo.connect似乎並沒有工作(正如我所期望的那樣)。

任何想法如何糾正?

下面是一些示例代碼(赦免長度)。我希望能夠從「lister」功能打印列出的文件/ URL。最後,我想,然後有一個功能制定新的URL &通過他們回到connectAndDownload下載每個文件的(當然,這需要修改connectAndDownload,但我們現在還沒有)。

#!/usr/bin/env python 

from PyQt4 import QtCore, QtGui, QtNetwork 

class FtpWorker(QtCore.QThread): 
    dataTransferProgress = QtCore.pyqtSignal(int,int) 
    def __init__(self,url,parent=None): 
     super(FtpWorker,self).__init__(parent) 
     self.ftp = None 
     self.outFile = None 
     self.get_index = -1 

     self.url = url 

    def run(self): 
     self.connectAndDownload() 
     self.exec_() 

    def ftpCommandFinished(self, command_index, error): 
     print "-----commandfinished-----",command_index 

     if self.ftp.currentCommand == QtNetwork.QFtp.ConnectToHost: 
      if error: 
       QtGui.QMessageBox.information(self, "FTP", 
         "Unable to connect to the FTP server at %s. Please " 
         "check that the host name is correct.") 
      return 

     if self.ftp.currentCommand == QtNetwork.QFtp.Get or command_index == self.get_index: 
      if error: 
       print "closing outfile prematurely" 
       self.outFile.close() 
       self.outFile.remove() 
      else: 
       print "closed outfile normally" 
       self.outFile.close() 

      self.outFile = None 

    def ftpDataTransferProgress(self,a,b): 
     self.dataTransferProgress.emit(a,b) 


    def lister(self,url_info): 
     print url_info.name() 


    def connectAndDownload(self): 
     if self.ftp: 
      self.ftp.abort() 
      self.ftp.deleteLater() 
      self.ftp = None 
      return 

     self.ftp = QtNetwork.QFtp() 
     self.ftp.commandFinished.connect(self.ftpCommandFinished) 
     self.ftp.listInfo.connect(self.lister) 
     self.ftp.dataTransferProgress.connect(self.ftpDataTransferProgress) 

     url = QtCore.QUrl(self.url) 

     print "connect",self.ftp.connectToHost(url.host(), url.port(21)) 
     print "login",self.ftp.login(url.userName(), url.password()) 


     print "Connecting to FTP server %s..." % str(url.host()) 

     import os 
     fileName = os.path.basename(self.url) 

     if QtCore.QFile.exists(fileName): 
      print "removing '%s'" % fileName 
      os.unlink(fileName) 

     self.outFile = QtCore.QFile(fileName) 
     if not self.outFile.open(QtCore.QIODevice.WriteOnly): 
      QtGui.QMessageBox.information(self, "FTP", 
        "Unable to save the file %s: %s." % (fileName, self.outFile.errorString())) 
      self.outFile = None 
      return 

     tmp = self.ftp.list() 
     print "starting list",tmp 

     print "ftp.get(%s,%s)" % (str(url.path()), self.outFile) 
     self.get_index = self.ftp.get(url.path(), self.outFile) 



class AddProgresWin(QtGui.QWidget): 
    def __init__(self, parent=None): 
     super(AddProgresWin, self).__init__(parent) 

     self.thread = FtpWorker(url="ftp://ftp.qt.nokia.com/developerguides/qteffects/screenshot.png") 

     self.thread.dataTransferProgress.connect(self.updateDataTransferProgress) 

     self.nameLabel = QtGui.QLabel("0.0%") 
     self.nameLine = QtGui.QLineEdit() 

     self.progressbar = QtGui.QProgressBar() 

     mainLayout = QtGui.QGridLayout() 
     mainLayout.addWidget(self.progressbar, 0, 0) 
     mainLayout.addWidget(self.nameLabel, 0, 1) 

     self.setLayout(mainLayout) 
     self.setWindowTitle("Processing") 

     self.thread.start() 

    def updateDataTransferProgress(self, readBytes, totalBytes): 
     self.progressbar.setMaximum(totalBytes) 
     self.progressbar.setValue(readBytes) 
     perct = "%2.1f%%" % (float(readBytes)/float(totalBytes)*100.0) 
     self.nameLabel.setText(perct) 


if __name__ == '__main__': 

    import sys 
    app = QtGui.QApplication(sys.path) 

    pbarwin = AddProgresWin() 
    pbarwin.show() 

    sys.exit(app.exec_()) 

回答

1

看來這是一個Qt錯誤。 Phil Thompson表示:「這可以說是一個Qt錯誤 - 它應該調用qRegisterMetaType()本身來處理信號參數中使用的任何類型。」

它也帶來了我的注意,爲了這個目的,就沒有必要到線程,爲QFtp是異步&都有自己的信號。我已經重新實現了主線程&中的ftp.list()(和相關的信號處理)。

相關問題