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

效果:

  •  不重写线程类 

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

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

效果:

 

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用QThreadPyQt5中开发多线程应用程序是很常见的,但有时候我们需要停止或者终止某个线程,这个时候要怎样做呢? PyQt5提供了一种简单有效的方式来终止线程,我们可以通过附加一个标志位来实现正常停止线程的操作。具体的过程如下: 1. 在需要终止的线程中定义一个布尔型变量,例如self._isRunning = True。 2. 在线程的run()方法中循环执行任务,并在合适的地方检查self._isRunning的状态。如果该变量为False,则结束循环并停止线程。 3. 在主线程中通过改变self._isRunning的值来控制线程的停止。 下面是一个简单的实例,演示如何通过设置布尔型变量来控制线程的停止: ```python import sys from PyQt5.QtCore import QThread, pyqtSignal from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout class TestThread(QThread): stop_signal = pyqtSignal() def __init__(self, parent=None): super(TestThread, self).__init__(parent) self._isRunning = True def run(self): while self._isRunning: print('Thread is running...') self.sleep(1) self.stop_signal.emit() def stop(self): self._isRunning = False class MainWindow(QWidget): def __init__(self): super(MainWindow, self).__init__() self.initUI() def initUI(self): self.btn_start = QPushButton('Start', self) self.btn_stop = QPushButton('Stop', self) layout = QVBoxLayout(self) layout.addWidget(self.btn_start) layout.addWidget(self.btn_stop) self.btn_start.clicked.connect(self.startThread) self.btn_stop.clicked.connect(self.stopThread) self.thread = TestThread() self.thread.stop_signal.connect(self.stopCompleted) def startThread(self): self.thread.start() def stopThread(self): self.thread.stop() def stopCompleted(self): print('Thread stopped successfully!') if __name__ == '__main__': app = QApplication(sys.argv) mainWindow = MainWindow() mainWindow.show() sys.exit(app.exec_()) ``` 上述代码中,我们新定义了一个停止信号stop_signal,并在stop()方法中发射该信号。同时,在主窗口中也连接了stop_signal信号,以实现停止线程后的回调操作。 总的来说,在PyQt5中终止线程很简单,只需要在线程类中设置布尔型的变量,通过在主线程中改变该变量的值即可控制线程的停止。在PyQt5中,线程的终止操作应该由主线程来完成,这是比较安全可靠的做法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值