Pyqt 使用 QThread 但 GUI 仍然没有响应

Pyqt use QThread but GUI still not responding

我尝试从 FTP 下载文件到网络共享文件夹(文件大小可能为 500mb 或更大)但每次单击 "Start" 时,即使使用 QThread,GUI 也会显示 "not responding"

我是不是做错了什么?

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

你确实做错了。

你现在做的是直接调用 run 方法,而不是你应该调用 start(),所以正确的实现应该是:

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

当子类化 QThread(或常规 python 线程)时,您实现 run 方法,它代表线程应该做的工作,如果您直接调用它,在 current 线程中执行该代码(在本例中是您的主线程)。这就是您的 GUI 将变得无响应的原因。

但是如果你改为调用 start(),它实际上会首先生成一个新线程(如果它尚不存在)然后调用 run。来自 PyQT Documentation:

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

Begins execution of the thread by calling run(). The operating system will schedule the thread according to the priority parameter. If the thread is already running, this function does nothing.

对于run()

QThread.run (self)

The starting point for the thread. After calling start(), the newly created thread calls this function.