从另一个运行FTP下载的线程更新PyQt进度 [英] Update PyQt progress from another thread running FTP download
问题描述
我想从另一个类/线程(DownloadThread()
类)访问进度条(在Ui_MainWindow()
类中)setMaximum()
.
I want to access progress bar's (which is in the Ui_MainWindow()
class) setMaximum()
from another class/thread (DownloadThread()
class).
我尝试使DownloadThread()
类继承自Ui_MainWindow
:
DownloadThread(Ui_MainWindow)
.但是,当我尝试设置最大进度条值时:
I tried making DownloadThread()
class inherit from Ui_MainWindow
:
DownloadThread(Ui_MainWindow)
. But when I try to set the maximum progress bar value:
Ui_MainWindow.progressBar.setMaximum(100)
我收到此错误:
AttributeError:类型对象'Ui_MainWindow'没有属性'progressBar'
AttributeError: type object 'Ui_MainWindow' has no attribute '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))
推荐答案
直接的问题是Ui_MainWindow
是一个类,而不是该类的实例.您必须将窗口" self
传递给DownloadThread
.但这毕竟不是正确的解决方案.您无法从其他线程访问PyQt小部件.相反,请使用与您已经使用的相同的技术来更新状态文本( 使用文本标签显示当前状态的FTP下载下载 ).
The immediate problem is that Ui_MainWindow
is a class, not an instance of the class. You would have to pass your "window" self
to the DownloadThread
. But that's not the right solution anyway. You cannot access PyQt widgets from another thread. Instead, use the same technique as you already do, to update the status text (FTP download with text label showing the current status of the download).
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
继承.
global localfile
is a bad practice. Useself.localfile
instead.- There's no need for
localfile.close()
,with
takes care of that. - Similarly
ftp.quit()
should be replaced withwith
. - There's no need for
DownloadThread
to inherit fromUi_MainWindow
.
这篇关于从另一个运行FTP下载的线程更新PyQt进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!