Pyqt использует QThread, но GUI все еще не отвечает

Я пытался загрузить файл с FTP в общую сетевую папку (размер файла может быть 500 МБ или больше), но каждый раз при нажатии "Пуск" графический интерфейс отображает "не отвечает" даже при использовании QThread

Я сделал что-то неправильно?

main.py

# -*- coding: utf-8 -*-
from PyQt4 import QtGui
import ftp100



class main_windows(QtGui.QWidget):
    def __init__(self):
        super(main_windows, self).__init__()
        self._count = 0
        self.Ftpallobject = []

    def init(self):

        #PASS SOME GUI CODE

        button_go = QtGui.QPushButton('GO')
        button_go.clicked.connect(self.Ftpstart)

        self.fp = ftp100.ftpmethod()
        self.fp.requestSignal_getinfo.connect(self.Ftpallobject)



    def SendFtpInfo(self):
        self.fp.update_getinfo.emit(self.allobject)

    def Ftpstart(self):
        self.fp.run()

ftp.py

# -*- coding: utf-8 -*-
from PyQt4 import QtCore
import ftputil

class ftpmethod(QtCore.QThread):
    requestSignal_getinfo = QtCore.pyqtSignal()
    update_getinfo = QtCore.pyqtSignal(list)

    def __init__(self, parent=None):
        super(ftpmethod, self).__init__(parent)
        self._count = 0
        self.ftpinfo = []
        self.update_getinfo.connect(self.getinfo)

    def run(self):
        self.requestSignal_getinfo.emit()
        while self._count<1:
            for i in self.ftpinfo:
                site = "".join(str(i[2].text()))
                account = "".join(str(i[0].text()))
                pwd = "".join(str(i[1].text()))
                filepath = "".join(str(i[3].text()))
                filename = "".join(str(i[4].text()))
                downloadtolocal = "".join(str(i[7].text()))+"".join(str(i[4].text()))
                print site,account,pwd,filepath,filename,downloadtolocal
                try:
                    with ftputil.FTPHost(site,account,pwd) as host:
                        if filepath=='':
                            host.download(filename,downloadtolocal)
                        else:
                            host.chdir(filepath)
                            host.download(filename,downloadtolocal)
                except:
                    print 'FTP ERROR'
            self._count+=1
        self._count=0

    def getinfo(self,info):
        self.ftpinfo = info

1 ответ

Решение

Вы действительно делаете это неправильно.

То, что вы делаете сейчас, это то, что вы называете run-метод напрямую, но вместо этого вы должны звонить start()поэтому правильная реализация должна быть:

def Ftpstart(self):
    self.fp.start()

Когда подклассы QThread (или обычный поток Python в этом отношении), вы реализуете run-method, представляющий работу, которую должен выполнять поток, и если вы вызываете его напрямую, вы выполняете этот код в текущем потоке (в данном случае ваш основной поток). Вот почему ваш графический интерфейс перестает отвечать на запросы.

Но если вы позвоните start() вместо этого он сначала создаст новый поток (если он еще не существует), а затем вызовет run, Из документации PyQT:

QThread.start (self, Priority priority = QThread.InheritPriority)

Начинает выполнение потока с вызова run(). Операционная система будет планировать поток в соответствии с параметром приоритета. Если поток уже запущен, эта функция ничего не делает.

И для run()

QThread.run (самостоятельно)

Начальная точка для потока. После вызова start() вновь созданный поток вызывает эту функцию.

Другие вопросы по тегам