Ответ 1
Я думаю, вы можете ошибаться. Вам нужна работа, которую вы делаете в отдельном потоке, чтобы она не затормозила приложение. Но вы также хотите обновить индикатор выполнения. Вы можете достичь этого, создав рабочий класс, используя QThread
. QThreads могут излучать сигналы, которые ваш пользовательский интерфейс может прослушивать и действовать соответствующим образом.
Сначала создайте свой рабочий класс.
#Inherit from QThread
class Worker(QtCore.QThread):
#This is the signal that will be emitted during the processing.
#By including int as an argument, it lets the signal know to expect
#an integer argument when emitting.
updateProgress = QtCore.Signal(int)
#You can do any extra things in this init you need, but for this example
#nothing else needs to be done expect call the super init
def __init__(self):
QtCore.QThread.__init__(self)
#A QThread is run by calling it start() function, which calls this run()
#function in it own "thread".
def run(self):
#Notice this is the same thing you were doing in your progress() function
for i in range(1, 101):
#Emit the signal so it can be received on the UI side.
self.updateProgress.emit(i)
time.sleep(0.1)
Итак, теперь, когда у вас есть рабочий класс, пришло время его использовать. Вам понадобится создать новую функцию в классе Ui_Dialog
для обработки испускаемых сигналов.
def setProgress(self, progress):
self.progressBar.setValue(progress)
Пока вы там, вы можете удалить свою функцию progress()
.
в retranslateUi()
вам нужно будет обновить обработчик событий кнопки с
self.pushButton.clicked.connect(self.progress)
к
self.pushButton.clicked.connect(self.worker.start)
Наконец, в вашей функции setupUI()
вам нужно будет создать экземпляр вашего рабочего класса и подключить его к вашей функции setProgress()
.
До этого:
self.retranslateUi(Dialog)
Добавьте это:
self.worker = Worker()
self.worker.updateProgress.connect(self.setProgress)
Вот окончательный код:
from PySide import QtCore, QtGui
import time
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 133)
self.progressBar = QtGui.QProgressBar(Dialog)
self.progressBar.setGeometry(QtCore.QRect(20, 10, 361, 23))
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.pushButton = QtGui.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(20, 40, 361, 61))
self.pushButton.setObjectName("pushButton")
self.worker = Worker()
self.worker.updateProgress.connect(self.setProgress)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.progressBar.minimum = 1
self.progressBar.maximum = 100
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Dialog", "PushButton", None, QtGui.QApplication.UnicodeUTF8))
self.progressBar.setValue(0)
self.pushButton.clicked.connect(self.worker.start)
def setProgress(self, progress):
self.progressBar.setValue(progress)
#Inherit from QThread
class Worker(QtCore.QThread):
#This is the signal that will be emitted during the processing.
#By including int as an argument, it lets the signal know to expect
#an integer argument when emitting.
updateProgress = QtCore.Signal(int)
#You can do any extra things in this init you need, but for this example
#nothing else needs to be done expect call the super init
def __init__(self):
QtCore.QThread.__init__(self)
#A QThread is run by calling it start() function, which calls this run()
#function in it own "thread".
def run(self):
#Notice this is the same thing you were doing in your progress() function
for i in range(1, 101):
#Emit the signal so it can be received on the UI side.
self.updateProgress.emit(i)
time.sleep(0.1)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
В QThreads есть встроенные сигналы, которые автоматически испускаются. Вы можете увидеть их и получить дополнительную информацию о QThreads в документации