【问题标题】:Pyqt use QThread but GUI still not respondingPyqt 使用 QThread 但 GUI 仍然没有响应
【发布时间】:2023-08-15 01:59:01
【问题描述】:

我尝试将文件从 FTP 下载到网络共享文件夹(文件大小可能 500mb 或更大)但每次单击“开始”时,即使使用 QThread,GUI 也会显示“无响应”

我做错什么了吗?

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

【问题讨论】:

    标签: python pyqt4 qthread ftputil


    【解决方案1】:

    你确实做错了。

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

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

    当子类化QThread(或常规python线程)时,你实现run-方法,它代表线程应该做的工作,如果你直接调用它,你在current 线程(所以在这种情况下你的主线程)。这就是您的 GUI 将变得无响应的原因。

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

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

    通过调用 run() 开始执行线程。操作系统会根据优先级参数调度线程。如果线程已经在运行,这个函数什么也不做。

    对于run()

    QThread.run (self)

    线程的起点。调用 start() 后,新 创建的线程调用这个函数。

    【讨论】: