在开发的过程中经常会遇到一些耗时的程序,然后程序就会卡在耗时程序段中,造成ui无法实时刷新,本例用qt线程实现计时程序和主程序同时进行计算操作,左边计时,右边可以进行计算操作,互不影响
-
重写线程类
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal
import sys
import time
class MyWin(QWidget):
def __init__(self):
super(MyWin, self).__init__()
self.setWindowTitle('QThread')
self.setupUi()
self.mythread = MyThread() # 实例化线程
self.mythread.signal.connect(self.customslot) #连接线程类中自定义信号槽到本类的自定义槽函数
self.mythread.start() #开启线程不是调用run函数而是调用start函数
def setupUi(self):
'''左边布局'''
self.lineEdit = QLineEdit()
self.lineEdit.setText('0')
self.layoutleft = QHBoxLayout()
self.layoutleft.addWidget(self.lineEdit)
self.left = QWidget()
self.left.setLayout(self.layoutleft)
self.left.setStyleSheet("QWidget{border: 1px solid #FF0000;}")
'''右边布局'''
self.btn = QPushButton('calculate')
self.btn.clicked.connect(self.add)
self.lineEdit1 = QLineEdit()
self.lineEdit2 = QLineEdit()
self.result = QLineEdit()
self.formlayout = QFormLayout()
# self.formlayout.setVerticalSpacing()
self.formlayout.addRow('加数1', self.lineEdit1)
self.formlayout.addRow('加数2', self.lineEdit2)
self.formlayout.addRow('计算结果', self.result)
self.vbox = QVBoxLayout()
self.vbox.addLayout(self.formlayout)
self.vbox.addWidget(self.btn)
self.right = QWidget()
self.right.setLayout(self.vbox)
self.right.setStyleSheet("QWidget{border: 1px solid #FF0000;}")
'''设置总布局'''
self.hbox = QHBoxLayout()
self.hbox.addWidget(self.left)
self.hbox.addWidget(self.right)
self.setLayout(self.hbox)
def add(self):
value = str(int(self.lineEdit1.text())+int(self.lineEdit2.text()))
self.result.setText(value)
def customslot(self, i):
self.lineEdit.setText(i)
class MyThread(QThread): #重写线程类
signal = pyqtSignal(str) #自定义一个pyqtSignal信号,信号参数是个字符串str类型
count = 0
def __init__(self):
super(MyThread, self).__init__()
def run(self):
while True:
self.signal.emit(str(self.count)) #发射信号
time.sleep(1)
self.count += 1
if __name__ == '__main__':
app = QApplication(sys.argv)
mywin = MyWin()
mywin.show()
sys.exit(app.exec())
效果:
-
不重写线程类
与上面不同的是添加了一条线程结束的信号,当线程结束后发射信号,接收到信号后调用退出线程的函数
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal, QObject, pyqtSlot
import sys
import time
class MyWin(QWidget):
def __init__(self):
super(MyWin, self).__init__()
self.setWindowTitle('QThread')
self.setupUi()
self.work = threadRun()
self.mythread = QThread() # 实例化线程
self.work.moveToThread(self.mythread) #处理程序移到线程中
self.work.start_signal.connect(self.customslot)
self.work.stop_signal.connect(self.stopThread)
self.mythread.started.connect(self.work.work)
self.mythread.start() # 开启线程不是调用run函数而是调用start函数
def setupUi(self):
'''左边布局'''
self.lineEdit = QLineEdit()
self.lineEdit.setText('0')
self.layoutleft = QHBoxLayout()
self.layoutleft.addWidget(self.lineEdit)
self.left = QWidget()
self.left.setLayout(self.layoutleft)
self.left.setStyleSheet("QWidget{border: 1px solid #FF0000;}")
'''右边布局'''
self.btn = QPushButton('calculate')
self.btn.clicked.connect(self.add)
self.lineEdit1 = QLineEdit()
self.lineEdit2 = QLineEdit()
self.result = QLineEdit()
self.formlayout = QFormLayout()
self.formlayout.addRow('加数1', self.lineEdit1)
self.formlayout.addRow('加数2', self.lineEdit2)
self.formlayout.addRow('计算结果', self.result)
self.vbox = QVBoxLayout()
self.vbox.addLayout(self.formlayout)
self.vbox.addWidget(self.btn)
self.right = QWidget()
self.right.setLayout(self.vbox)
self.right.setStyleSheet("QWidget{border: 1px solid #FF0000;}")
'''设置总布局'''
self.hbox = QHBoxLayout()
self.hbox.addWidget(self.left)
self.hbox.addWidget(self.right)
self.setLayout(self.hbox)
def add(self):
value = str(int(self.lineEdit1.text()) + int(self.lineEdit2.text()))
self.result.setText(value)
def customslot(self, i):
self.lineEdit.setText(str(i))
def stopThread(self):
self.lineEdit.setText('线程结束')
self.mythread.exit() #调用线程退出函数
class threadRun(QObject):
start_signal = pyqtSignal(int)
stop_signal = pyqtSignal()
@pyqtSlot()
def work(self): # A slot takes no params
for i in range(1, 10):
time.sleep(1)
self.start_signal.emit(i)
self.stop_signal.emit()
if __name__ == '__main__':
app = QApplication(sys.argv)
mywin = MyWin()
mywin.show()
sys.exit(app.exec())
效果: