引言
学习多线程最典型的问题就是如何在多个线程之间传递消息与写作,PyQT5的线程支持在不同线程之间传递信号触发事件,实现多个线程之间的协助,完成诸如生产者-消费者这样经典的多线程协作。本文将通过QThread与信号槽机制构建一个生产者-消费者模型,演示多个线程之间的协作。
应用程序概述
这里演示了一个从图像采集(用本地图像数据集替代)到图像分析处理(简单二值化+形态学处理)、到主界面更新的应用程序。主界面是UI线程、图像采集跟图像分析分别在两个不同的工作线程中,通过信号与槽机制协作工作,相互配合实现图像采集到分析到结果更新到界面线程。
多线程协作信号触发示意图
代码实现
这样实现了三个类
ImageFetchThread // 图像采集 ImageAnalysisThread // 图像分析 ContentPanel // 界面显示与更新
这三个类的代码分别,模拟图像采集线程
1classImageFetchThread(QtCore.QThread): 2fire_stats_signal=QtCore.pyqtSignal(dict) 3 4def__init__(self,images_dir): 5super(ImageFetchThread,self).__init__() 6self.images_dir=images_dir 7self.read_next=True 8 9defrequest_image(self): 10self.read_next=True 11 12defrun(self): 13iflen(self.images_dir)==0: 14return 15files=os.listdir(self.images_dir) 16idx=0 17whileTrue: 18ifidx==len(files): 19break 20ifself.read_nextisTrue: 21print("graboneimage...") 22image=cv.imread(os.path.join(self.images_dir,files[idx])) 23gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) 24idx+=1 25self.read_next=False 26self.fire_stats_signal.emit({"im_data":gray}) 27self.fire_stats_signal.emit({"done":"done"}) 28return
处理图像线程
1classImageAnalysisThread(QtCore.QThread): 2request_image_signal=QtCore.pyqtSignal() 3update_result_signal=QtCore.pyqtSignal(dict) 4 5def__init__(self): 6super(ImageAnalysisThread,self).__init__() 7self.image_data=None 8self.stop=False 9 10defprocess_im(self,results): 11self.image_data=results.get("im_data") 12ifresults.get("done")isnotNone: 13self.stop=True 14 15defrun(self): 16whileTrue: 17ifself.stopisTrue: 18break 19ifself.image_dataisNone: 20continue 21print("startedtoprocessoneimage...") 22#ret,binary=cv.threshold(self.image_data,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU) 23binary=cv.adaptiveThreshold(self.image_data,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C, 24cv.THRESH_BINARY_INV,25,10) 25se=cv.getStructuringElement(cv.MORPH_RECT,(7,7)) 26resutl=cv.morphologyEx(binary,cv.MORPH_DILATE,se) 27self.request_image_signal.emit() 28self.update_result_signal.emit({"im_data":resutl}) 29self.image_data=None 30self.update_result_signal.emit({"done":"done"}) 31return
界面线程
1classContentPanel(QtWidgets.QWidget): 2def__init__(self,parent=None): 3super().__init__(parent) 4fileBtn=QtWidgets.QPushButton("目录...") 5self.image_files_dir=QtWidgets.QLineEdit() 6self.image_files_dir.setMinimumWidth(100) 7self.image_files_dir.setEnabled(False) 8self.processBtn=QtWidgets.QPushButton("开始处理") 9hbox_layout=QtWidgets.QHBoxLayout() 10hbox_layout.addWidget(fileBtn) 11hbox_layout.addWidget(self.image_files_dir) 12hbox_layout.addWidget(self.processBtn) 13panel1=QtWidgets.QGroupBox("目录选择") 14panel1.setLayout(hbox_layout) 15 16#图像标签 17self.imgLabel=QtWidgets.QLabel() 18self.imgLabel.setMinimumSize(800,600) 19self.imgLabel.setStyleSheet("background-color:black;color:deeppink") 20self.imgLabel.setAlignment(QtCore.Qt.AlignCenter) 21 22#添加到布局管理器中 23vbox_layout=QtWidgets.QVBoxLayout() 24vbox_layout.addWidget(panel1) 25vbox_layout.addWidget(self.imgLabel) 26vbox_layout.addStretch(1) 27 28#面板容器 29self.setLayout(vbox_layout) 30 31#setuplistener 32fileBtn.clicked.connect(self.on_select_image_dir) 33self.processBtn.clicked.connect(self.on_process) 34 35self.fetch_thread=None 36self.analysis_thread=None 37 38defon_select_image_dir(self): 39img_dir=QtWidgets.QFileDialog.getExistingDirectory(self,"图像文件夹",".") 40self.image_files_dir.setText(img_dir)
演示部分
审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
多线程
+关注
关注
0文章
271浏览量
19724 -
应用程序
+关注
关注
37文章
3136浏览量
56391 -
OpenCV
+关注
关注
29文章
611浏览量
40775 -
图像分析
+关注
关注
0文章
80浏览量
18562 -
pyqt5
+关注
关注
0文章
25浏览量
3361
原文标题:PyQT5+OpenCV多线程协作演示
文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
Java多线程的用法
本文将介绍一下Java多线程的用法。 基础介绍 什么是多线程 指的是在一个进程中同时运行多个线程,每个线程都可以独立执行不同的任务或操作。 与单线程
可视可交互!H618上用OpenCV读取图像显示到PyQt5窗口上
这里分享一个代码,功能是使用图像处理库opencv从摄像头获取数据,缩放后从pyqt5的窗口中显示出来。安装opencvsudo pip3 install opencv-python创建一个
发表于 01-10 09:55
QNX环境下多线程编程
介绍了QNX 实时操作系统和多线程编程技术,包括线程间同步的方法、多线程程序的分析步骤、线程基本程序结构以及实用编译方法。QNX 是由加拿大QNX 软件有限系统公司开发的
发表于 08-12 17:37
•30次下载
多线程在VC++串口通信程序中的应用
本文通过一机房监控系统程序中串口通信对多线程的应用来介绍Windows 9X/NT操作系统中多线程的应用和VC++对多线程的支持。关健词: 多线程,串口通信在现代的各种实时监控系
发表于 09-03 11:45
•27次下载
多线程与聊天室程序的创建
多线程程序的编写,多线程应用中容易出现的问题。互斥对象的讲解,如何采用互斥对象来实现多线程的同步。如何利用命名互斥对象保证应用程序只有一个实例运行。应用多线程编写网络聊天室程序。
发表于 05-16 15:22
•0次下载
linux多线程编程技术
1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者。传统的 Unix也支持线程的概念,但是在一个进程
发表于 10-24 16:01
•5次下载
什么是多线程编程?多线程编程基础知识
摘要:多线程编程是现代软件技术中很重要的一个环节。要弄懂多线程,这就要牵涉到多进程。本文主要以多线程编程以及多线程编程相关知识而做出的一些结论。
发表于 12-08 16:30
•1.2w次阅读
Java多线程永动任务 多线程异步任务项目解读
1. 功能说明 2. 多线程任务示例 2.1 线程池 2.2 单个任务 2.3 任务入口 2.4 结果分析 2.5 源码地址 3. 写在最后 大家好,今天教大家撸一个 Java 的多线程永动任务
PyQT5+OpenCV开发的应用如何打包发布?
我自己用PyQT5写了一个应用程序,基本上都写好了,到了打包发布这个环节,我知道的有两个工具可以帮我打包分别是。
OpenCV+PyQT5开发桌面应用几个重要的坑与解决
大概去年八月份的时候,我打算用OpenCV+PyQT5开发一套OpenCV教学演示与快速验证桌面软件,说实话那个时候我对PyQT5的理解就是Hello World水平。经过一年多开发锤
多线程事务怎么回滚?一个简单示例演示多线程事务
在spring中可以使用@Transactional注解去控制事务,使出现异常时会进行回滚,在多线程中,这个注解则不会生效,如果主线程需要先执行一些修改数据库的操作,当子线程在进行处理出现异常时,主
发表于 08-09 12:22
•375次阅读
多线程如何保证数据的同步
多线程编程是一种并发编程的方法,意味着程序中同时运行多个线程,每个线程可独立执行不同的任务,共享同一份数据。由于多线程并发执行的特点,会引发数据同步的问题,即保证多个
评论