PyQt5 QThread应用

在开发的过程中经常会遇到一些耗时的程序,然后程序就会卡在耗时程序段中,造成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())

效果:

PyQt5 QThread应用_第1张图片

  •  不重写线程类 

与上面不同的是添加了一条线程结束的信号,当线程结束后发射信号,接收到信号后调用退出线程的函数 

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

效果:

PyQt5 QThread应用_第2张图片

 

 

你可能感兴趣的:(PyQt5)