小编典典

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

python

我想访问进度条的(这是在Ui_MainWindow()类)setMaximum()从另一个类/线程(DownloadThread()类)。

我尝试使DownloadThread()类继承自Ui_MainWindow
DownloadThread(Ui_MainWindow)。但是,当我尝试设置最大进度条值时:

Ui_MainWindow.progressBar.setMaximum(100)

我收到此错误:

AttributeError:类型对象“ Ui_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))

阅读 145

收藏
2021-01-20

共1个答案

小编典典

直接的问题是那Ui_MainWindow是一个类,而不是该类的实例。您必须将“窗口”self传递给DownloadThread。但这毕竟不是正确的解决方案。您无法从其他线程访问PyQt小部件。相反,请使用与您已经使用的相同的技术来更新状态文本(
带有文本标签的FTP下载,其中显示了下载的当前状态 )。

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)))

您的代码的其他更改:

  • global localfile是一个坏习惯。使用self.localfile代替。
  • 不需要localfile.close(),无需with担心。
  • 同样ftp.quit()应替换为with
  • 无需DownloadThread从继承Ui_MainWindow
2021-01-20