我想制作一个在线程上运行的progressbar,我希望能够在此过程中移动小部件:
import sys
from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, QLineEdit, QLabel, QComboBox, QProgressBar, QFileDialog
from PyQt4.QtCore import QSize, pyqtSlot, QCoreApplication, SIGNAL, QThread
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.setGeometry(500, 300, 820, 350)
self.setWindowTitle("Program")
self.initUI()
def initUI(self):
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('Load', self)
self.btn4.move(btnposx,btnposy+220)
self.connect(self.btn4, SIGNAL("released()"), self.test)
#ProgressBar
self.pb = QProgressBar(self)
self.pb.move(btnposx+150,btnposy+220)
self.pb.resize(470,27)
self.show()
def load(self, val):
self.pb.setValue(val)
def test(self):
self.workThread = WorkThread()
self.connect( self.workThread, SIGNAL('pb_update'), self.load)
self.workThread.start()
class WorkThread(QThread):
def __init__(self):
super(WorkThread, self).__init__()
QThread.__init__(self)
def __del__(self):
self.wait()
@pyqtSlot()
def run(self):
val = 0
l = range(1000000)
for i in l:
if i < len(l):
val += 100/len(l)
self.emit(SIGNAL('pb_update'), val)
return
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
到目前为止,这有效,但确实很差。当我尝试在此过程中移动它时,小部件确实几乎不在我的机器上运行。有没有办法使此工作更好,以使小部件不会落后或停止响应?
您的代码可以进行的改进如下:
- 使用信号和插槽之间的新连接样式
- 您必须留出一些时间才能使辅助线程将信息发送到主线程。
- 您必须指示连接类型,在您的情况下
Qt::QueuedConnection
。 - 使用
pyqtSlot
装饰器。 - 您只需要在必要时发出信号,在您的情况下,当值的全部值变化时,因为
QProgressBar
无法识别浮动。
import sys
from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, QLineEdit, QLabel, QComboBox, QProgressBar, QFileDialog
from PyQt4.QtCore import QSize, pyqtSlot, pyqtSignal, QThread, Qt
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.setGeometry(500, 300, 820, 350)
self.setWindowTitle("Program")
self.initUI()
def initUI(self):
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('Load', self)
self.btn4.move(btnposx,btnposy+220)
self.btn4.released.connect(self.test)
#ProgressBar
self.pb = QProgressBar(self)
self.pb.move(btnposx+150,btnposy+220)
self.pb.resize(470,27)
self.show()
@pyqtSlot(int)
def load(self, val):
self.pb.setValue(val)
def test(self):
self.workThread = WorkThread()
self.workThread.pb_update.connect(self.load, Qt.QueuedConnection)
#self.workThread.pb_update.connect(self.pb.setValue)
self.workThread.start()
class WorkThread(QThread):
pb_update = pyqtSignal(float)
def __init__(self, *args, **kwargs):
QThread.__init__(self, *args, **kwargs)
self.value = 0
def __del__(self):
self.wait()
@pyqtSlot()
def run(self):
val = 0
l = range(1000000)
for i in l:
if i < len(l):
val += 100/len(l)
int_val = int(val)
if int_val != self.value:
self.value = int_val
self.pb_update.emit(self.value)
QThread.msleep(1)
return
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())