PyQt thread ftp:无法对'QUrlInfo'类型的参数进行排队

时间:2012-11-20 02:03:06

标签: pyqt signals qthread

我需要下载ftp目录中的所有文件。我的程序启动时我不知道目录中的文件,所以我希望程序列出目录的内容,然后下载它找到的每个文件。

我制作了一个小脚本,可以从ftp&这样做时更新进度条。下载&更新进度条工作正常,但是,我正在尝试进行下一步,即列出某些目录和内容的内容。下载文件,那部分不起作用。

目前,我只是想在任何目录上做一个列表&将结果打印到命令行。

当我尝试执行listInfo.connect时,收到错误消息:

QObject :: connect:无法对'QUrlInfo'类型的参数进行排队 (确保使用qRegisterMetaType()注册'QUrlInfo'。)

...据我了解,qRegisterMetaType不是可以在PyQt&中完成的事情。也是一个根本问题的标志,这就是我的问题。我可以做一个commandFinished.connect和dataTransferProgress.connect没有问题,但listInfo.connect似乎不起作用(正如我所料)。

任何想法如何纠正这个?

这是一些示例代码(请原谅长度)。我希望能够从“lister”函数打印列出的文件/ 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 个答案:

答案 0 :(得分:1)

看来这是一个Qt错误。来自Phil Thompson,“它可以说是一个Qt bug - 它应该为信号参数中使用的任何类型调用qRegisterMetaType()本身。”

我还注意到,为此目的,没有必要进行线程化,因为QFtp是异步的&有自己的信号。我已经重新实现了主线程&中的ftp.list()(以及相关的信号处理)。一切都很好。