Python 从另一个运行FTP下载的线程更新PyQt进度

Python 从另一个运行FTP下载的线程更新PyQt进度,python,ftp,pyqt,progress-bar,ftplib,Python,Ftp,Pyqt,Progress Bar,Ftplib,我想从另一个类/线程(DownloadThread()class)访问进度条(在Ui\u主窗口()class中) 我试图使DownloadThread()类继承自Ui\u主窗口: 下载线程(Ui\u主窗口)。但当我尝试设置最大进度条值时: Ui_MainWindow.progressBar.setMaximum(100) 我得到这个错误: AttributeError:类型对象“Ui\u MainWindow”没有属性“progressBar” 我的代码: class Ui_MainWindo

我想从另一个类/线程(
DownloadThread()
class)访问进度条(在
Ui\u主窗口()
class中)

我试图使
DownloadThread()
类继承自
Ui\u主窗口
下载线程(Ui\u主窗口)
。但当我尝试设置最大进度条值时:

Ui_MainWindow.progressBar.setMaximum(100)
我得到这个错误:

AttributeError:类型对象“Ui\u MainWindow”没有属性“progressBar”

我的代码:

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        # ...
        self.updateButton = QtGui.QPushButton(self.centralwidget)
        self.progressBar = QtGui.QProgressBar(self.centralwidget)
        self.updateStatusText = QtGui.QLabel(self.centralwidget)
        # ...
        self.updateButton.clicked.connect(self.download_file)
        # ...

    def download_file(self):
        self.thread = DownloadThread()
        self.thread.data_downloaded.connect(self.on_data_ready)
        self.thread.start()

    def on_data_ready(self, data):
        self.updateStatusText.setText(str(data))


class DownloadThread(QtCore.QThread, Ui_MainWindow):

    data_downloaded = QtCore.pyqtSignal(object)

    def run(self):
        self.data_downloaded.emit('Status: Connecting...')

        ftp = FTP('example.com')
        ftp.login(user='user', passwd='pass')

        ftp.cwd('/some_directory/')

        filename = '100MB.bin'
        totalsize = ftp.size(filename)
        print(totalsize)

        # SET THE MAXIMUM VALUE OF THE PROGRESS BAR
        Ui_MainWindow.progressBar.setMaximum(totalsize)          

        self.data_downloaded.emit('Status: Downloading...')

        global localfile
        with open(filename, 'wb') as localfile:
            ftp.retrbinary('RETR ' + filename, self.file_write)

        ftp.quit()
        localfile.close()

        self.data_downloaded.emit('Status: Updated!')

    def file_write(self, data):
        global localfile
        localfile.write(data)
        print(len(data))
线程类:

from PyQt5 import QtCore, QtGui, QtWidgets, QtPrintSupport,QtWebEngineWidgets
from PyQt5.QtWidgets import QDialog,QWidget,QApplication, QInputDialog, QLineEdit, QFileDialog,QProgressDialog, QMainWindow, QFrame,QSplashScreen
from PyQt5.QtCore import QThread , pyqtSignal,Qt
from PyQt5.QtGui import QIcon,QPainter,QPixmap

class threaded_class(QThread):

    signal_to_send_at_progress_bar = pyqtSignal()
    def __init__(self,parent=None):
        QThread.__init__(self, parent=parent)
    def run(self):
        while self.isRunning:
            ##do the stuf you want here and when you want to change the progress bar
            self.signal_to_send_at_progress_bar.emit()
在主窗口中:

class mainProgram(QtWidgets.QMainWindow, Ui_MainWindow):                   #main window


    def __init__(self, parent=None):

        super(mainProgram, self).__init__(parent)
        self.setupUi(self)
        ###...........#####
        self.thread_class_in_main_window = threaded_class()
        self.thread_class_in_main_window .start()
        self.thread_db.signal_to_send_at_progress_bar.connect(progressBar.setMaximum(100))

您还可以发出带有信号的字符串和数字。

直接的问题是,
Ui\u MainWindow
是一个类,而不是该类的实例。您必须将“窗口”
self
传递给
下载线程
。但无论如何,这不是正确的解决方案。您无法从其他线程访问PyQt小部件。相反,请使用与之前相同的技术来更新状态文本()

对代码的其他更改:

  • 全局本地文件
    是一种不好的做法。改用
    self.localfile
  • 不需要
    localfile.close()
    一起处理这个问题
    
  • 类似地,
    ftp.quit()
    应替换为
    with
  • 无需从
    Ui\u主窗口
    继承
    DownloadThread

请发布一个。我想你调用的是一个线程类,因此你需要一个信号来执行此操作,并从主窗口访问进度条@u917;άγγελογ962;ρηγορόπογλογογογογογογογογογογογογοθγ,
全局本地文件
是一种不好的做法。改用
self.localfile
。+无需使用
self.localfile.close()
with
会解决这个问题无需从
Ui\u主窗口继承
DownloadThread
——我在回答中也纠正了这一点。
class Ui_MainWindow(object):
    def download_file(self):
        self.thread = DownloadThread()
        self.thread.data_downloaded.connect(self.on_data_ready)
        self.thread.data_progress.connect(self.on_progress_ready)
        self.progress_initialized = False
        self.thread.start()

    def on_progress_ready(self, data):
        # The first signal sets the maximum, the other signals increase a progress
        if self.progress_initialized:
            self.progressBar.setValue(self.progressBar.value() + int(data))
        else:
            self.progressBar.setMaximum(int(data))
            self.progress_initialized = True

class DownloadThread(QtCore.QThread):

    data_downloaded = QtCore.pyqtSignal(object)
    data_progress = QtCore.pyqtSignal(object)

    def run(self):
        self.data_downloaded.emit('Status: Connecting...')

        with FTP('example.com') as ftp:
            ftp.login(user='user', passwd='pass')

            ftp.cwd('/some_directory/')

            filename = '100MB.bin'
            totalsize = ftp.size(filename)
            print(totalsize)

            # The first signal sets the maximum
            self.data_progress.emit(str(totalsize))

            self.data_downloaded.emit('Status: Downloading...')

            with open(filename, 'wb') as self.localfile:
                ftp.retrbinary('RETR ' + filename, self.file_write)

        self.data_downloaded.emit('Status: Updated!')

    def file_write(self, data):
        self.localfile.write(data)
        # The other signals increase a progress
        self.data_progress.emit(str(len(data)))