简单介绍

在pyqt5中,如果不是特别复杂的程序,不建议手动操作线程,因为有时候不知道会发生什么致命的bug,在qt中操作线程的简单说明:

QWaitCondition()用于多线程同步,一个线程调用QWaitCondition.wait()阻塞等待,
直到另外一个线程调用QWaitCondition.wake()唤醒才继续往下执行
QMutex():是锁对象

线程执行的时候需要先上锁,并在运行的时候,定义一个判断标志,如果该标志触发就执行线程的挂起,直到再次唤醒。

案例一

主程序启动一个多线程,同时启动一个QDialog弹窗,将线程执行的结果交给dialog做展示,为了方便观察,将线程的执行结果在主程序界面跟dialog界面的QListWidget同时展示,除此之外,在dialog弹窗关闭后,也要触发线程关闭动作。

代码如下:

import sys
import timefrom PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QWaitCondition, QMutex
from PyQt5.QtWidgets import QWidget, QApplication, QDialog, QHBoxLayout, QListWidgetclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(400, 300)self.verticalLayout_2 = QtWidgets.QVBoxLayout(Form)self.verticalLayout_2.setObjectName("verticalLayout_2")self.horizontalLayout = QtWidgets.QHBoxLayout()self.horizontalLayout.setObjectName("horizontalLayout")self.verticalLayout = QtWidgets.QVBoxLayout()self.verticalLayout.setSpacing(30)self.verticalLayout.setObjectName("verticalLayout")spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)self.verticalLayout.addItem(spacerItem)self.start_btn = QtWidgets.QPushButton(Form)self.start_btn.setObjectName("start_btn")self.verticalLayout.addWidget(self.start_btn)self.pause_btn = QtWidgets.QPushButton(Form)self.pause_btn.setObjectName("pause_btn")self.verticalLayout.addWidget(self.pause_btn)self.resume_btn = QtWidgets.QPushButton(Form)self.resume_btn.setObjectName("resume_btn")self.verticalLayout.addWidget(self.resume_btn)self.stop_btn = QtWidgets.QPushButton(Form)self.stop_btn.setObjectName("stop_btn")self.verticalLayout.addWidget(self.stop_btn)spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)self.verticalLayout.addItem(spacerItem1)self.horizontalLayout.addLayout(self.verticalLayout)self.listWidget = QtWidgets.QListWidget(Form)self.listWidget.setObjectName("listWidget")self.horizontalLayout.addWidget(self.listWidget)self.verticalLayout_2.addLayout(self.horizontalLayout)self.retranslateUi(Form)QtCore.QMetaObject.connectSlotsByName(Form)def retranslateUi(self, Form):_translate = QtCore.QCoreApplication.translateForm.setWindowTitle(_translate("Form", "Form"))self.start_btn.setText(_translate("Form", "开始"))self.pause_btn.setText(_translate("Form", "暂停"))self.resume_btn.setText(_translate("Form", "唤醒"))self.stop_btn.setText(_translate("Form", "停止"))# 主程序点击后,会有弹窗
class Show_msg(QDialog):quit_trig = pyqtSignal()def __init__(self, parent=None):super(Show_msg, self).__init__(parent)self.initUi()def initUi(self):hLayout = QHBoxLayout()self.list_msg = QListWidget()hLayout.addWidget(self.list_msg)self.setLayout(hLayout)self.setWindowTitle('弹窗显示')def msg_setValue(self, msg):self.list_msg.addItem(msg)def closeEvent(self, event):self.quit_trig.emit()       # 关闭弹窗时,发出关闭信号,让主程序的进程关闭event.accept()passclass ThreadStopTest(QWidget, Ui_Form):def __init__(self):super(ThreadStopTest, self).__init__()self.setupUi(self)self.setWindowTitle('主程序窗口')self.handle()def handle(self):self.start_btn.clicked.connect(self.start_thread)self.stop_btn.clicked.connect(self.stop_thread)self.pause_btn.clicked.connect(self.pause_thread)self.resume_btn.clicked.connect(self.resume_thread)def start_thread(self):self.msg_dialog = Show_msg(self)     # 点击开始按钮后加载弹窗self.msg_dialog.show()               # 显示弹窗self.msg_dialog.quit_trig.connect(self.stop_thread)      # 将弹窗中的退出信号绑定到退出线程的方法上self.t = My_thread()    # 实例化一个线程,i并启动self.t.num_trig.connect(self.setValue)                   # 线程信号绑定到主程序listWidget上self.t.num_trig.connect(self.msg_dialog.msg_setValue)    # 线程信号绑定到弹窗中的listWidget上self.t.start()# 暂停线程def pause_thread(self):if self.t:self.t.pause()# 唤醒线程def resume_thread(self):if self.t:self.t.resume()# 停止线程def stop_thread(self):if self.t:self.t.terminate()self.t = Noneself.msg_dialog.close()     # 停止线程时,关闭弹窗else:self.listWidget.addItem('线程不存在')def setValue(self, v):self.listWidget.addItem(v)class My_thread(QThread):num_trig = pyqtSignal(str)def __init__(self):super(My_thread, self).__init__()'''QWaitCondition()用于多线程同步,一个线程调用QWaitCondition.wait()阻塞等待,直到另外一个线程调用QWaitCondition.wake()唤醒才继续往下执行QMutex():是锁对象'''self._isPause = Falseself.cond = QWaitCondition()self.mutex = QMutex()def run(self) -> None:a = 0while True:self.mutex.lock()       # 上锁if self._isPause:self.cond.wait(self.mutex)self.num_trig.emit(f'item{a}')a += 1QThread.sleep(2)self.mutex.unlock()  # 解锁# 线程暂停def pause(self):self._isPause = True# 线程恢复def resume(self):self._isPause = Falseself.cond.wakeAll()if __name__ == '__main__':# PyQt5高清屏幕自适应设置,以及让添加的高清图标显示清晰,不然designer导入的图标在程序加载时会特别模糊QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)app = QApplication(sys.argv)main_win = ThreadStopTest()main_win.show()sys.exit(app.exec_())

案例二

主界面定义一个进度条,两个按钮,一个休眠,一个唤醒,点击休眠,线程挂起,点击恢复,线程被唤起。

案例二引用自:04-QThread子线程的创建方式与线程挂起、唤醒 | PyQt - _vscode - 博客园

from PyQt5.QtCore import QThread, QWaitCondition, QMutex, pyqtSignal, Qt
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QProgressBar, QApplicationclass Thread(QThread):valueChange = pyqtSignal(int)def __init__(self, *args, **kwargs):super(Thread, self).__init__(*args, **kwargs)self._isPause = Falseself._value = 0self.cond = QWaitCondition()self.mutex = QMutex()def pause(self):self._isPause = Truedef resume(self):self._isPause = Falseself.cond.wakeAll()def run(self):while 1:self.mutex.lock()if self._isPause:self.cond.wait(self.mutex)if self._value > 100:self._value = 0self._value += 1self.valueChange.emit(self._value)self.msleep(100)self.mutex.unlock()class Window(QWidget):def __init__(self, *args, **kwargs):super(Window, self).__init__(*args, **kwargs)layout = QVBoxLayout(self)self.progressBar = QProgressBar(self)layout.addWidget(self.progressBar)layout.addWidget(QPushButton('休眠', self, clicked=self.doWait))layout.addWidget(QPushButton('唤醒', self, clicked=self.doWake))self.t = Thread(self)self.t.valueChange.connect(self.progressBar.setValue)self.t.start()def doWait(self):self.t.pause()def doWake(self):self.t.resume()if __name__ == '__main__':import sys# import cgitbQApplication.setAttribute(Qt.AA_EnableHighDpiScaling)QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)# cgitb.enable(format='text')app = QApplication(sys.argv)w = Window()w.show()sys.exit(app.exec_())

pyqt5线程的启动,暂停,恢复与停止相关推荐

  1. Qt之线程的开始暂停恢复停止

    一.前言 软件开发中,使用到线程就不可避免的要实现线程的暂停恢复停止等操作,总不可能说线程一旦启动就直接运行到结束了,中途不能停止啥的.线程的开始以及结束都比较简单,都有对应的接口可以调用,线程的暂停 ...

  2. 线程的启动暂停和终止

    线程的启动暂停和终止,听起来很简单,不过经常有初学者在这个问题上卡住,经常是启动了,能暂停,但再要启动就不行了,其实这个问题比较容易解决,思路也很简单,就是在启动线程的时候用一个判断语句锁定整个run ...

  3. python 实现线程的暂停, 恢复, 退出详解及实例

    Python中可以是threading模块实现多线程, 但是模块并没有提供暂停, 恢复和停止线程的方法, 一旦线程对象调用start方法后, 只能等到对应的方法函数运行完毕. 也就是说一旦start后 ...

  4. python暂停和恢复_python-线程的暂停, 恢复, 退出

    我们都知道python中可以是threading模块实现多线程, 但是模块并没有提供暂停, 恢复和停止线程的方法, 一旦线程对象调用start方法后, 只能等到对应的方法函数运行完毕. 也就是说一旦s ...

  5. Python关于Threading暂停恢复解决办法

    我们都知道python中可以是threading模块实现多线程, 但是模块并没有提供暂停, 恢复和停止线程的方法, 一旦线程对象调用start方法后, 只能等到对应的方法函数运行完毕. 也就是说一旦s ...

  6. python下载文件暂停恢复_Python关于Threading暂停恢复解决办法

    我们都知道python中可以是threading模块实现多线程, 但是模块并没有提供暂停, 恢复和停止线程的方法, 一旦线程对象调用start方法后, 只能等到对应的方法函数运行完毕. 也就是说一旦s ...

  7. c#语言窗体运行暂停指令,C#线程启动、暂停、恢复、停止怎么实现

    论坛的高手你们好,本人是一个菜鸟,肯请大家帮个忙实现如下功能: 首先窗体界面如下: 怎么实现"start"启动线程."pause"暂停线程."resu ...

  8. C++ :线程的暂停、恢复和停止

    转载:C++11: 线程的暂停和继续和停止_hai7song的专栏-CSDN博客_c++ 线程暂停 重点: 通过设置一个类,类里面加入线程,然后采用标志位来控线程的暂停.恢复和停止. 有点意思! #i ...

  9. java线程的停止,暂停,恢复*

    暂停.恢复和停止操作对应在线程Thread的API就是suspend().resume()和stop().但是这些API是过期的,也就是不建议使用的.不建议使用的原因主要有: 以suspend()方法 ...

最新文章

  1. java.lang.exception_java.lang.RuntimeException和java.lang.Exception
  2. ImageNet识别率一次提高1%:谷歌AI新突破引Jeff Dean点赞
  3. 神经网络侧枝抑制(自编码)
  4. Web应用扫描工具Wapiti
  5. Android开源之行之走进zxing,轻松实现二维码扫描(二)
  6. Readhat中升级openssh
  7. Hello,My first blog!
  8. 做骨龄检测_小柚熊:骨龄测试最佳年龄
  9. java index.jsp为什么不默认跳转_Java开发人员怎么面试 常见Redis面试题有哪些
  10. python中trun是什么意思_Python 中 'unicodeescape' codec can't decode bytes in position XXX: trun错误解...
  11. pip下载更新及采用镜像安装numpy、matplotlib等包
  12. 【今日CV 计算机视觉论文速览 第108期】Tue, 30 Apr 2019
  13. 测试人如何快速晋升为月薪过万的软件测试工程师?
  14. 【整理】显微镜下人体细胞视频合集
  15. Stressful Training(二分+贪心+优先队列)
  16. 百度违规屏蔽关键词工具
  17. Linux基础----文件管理、用户管理、用户权限
  18. 嵌入式系统实用电源管理技术应该如何选择?
  19. golang的基本语法
  20. E-puck机器人-小白学习笔记(二)代码浅解读

热门文章

  1. 使用基于变量交互学习的合作协同进化的大规模全局优化
  2. 学生管理系统html js,学生信息管理系统JS版(Eclipse).docx
  3. 用C语言编写一个3*3矩阵的转置、水平镜像、顺时针90度旋转、逆时针90度旋转、180度旋转、垂直镜像
  4. C++计算对称矩阵的实特征值和特征向量(附完整源码)
  5. bt开源的客户端——xbt client
  6. 上海民办中芯学校学生返校开学
  7. 介绍SFTP命令的用法-动手实践操作很重要
  8. Talk | 微软亚洲研究院宋恺涛南大余博涛:面向文本/音乐序列任务的Transformer注意力机制设计
  9. MFC对话框使用CPrintDialog实现打印,指定打印机、后台打印
  10. iTween研究院之学习笔记Move移动篇