PYQT5多线程加载图片

PYQT5多线程加载图片

1.步骤

在PyQt5的多线程中显示图片,可以按以下步骤实现:

  1. 定义一个继承自QThread的线程类,在其run()方法中加载图片并发射信号。
  2. 在主线程中创建线程类的实例,连接信号和槽,并启动线程。
  3. 在槽方法中,接收从线程发射的图像,并更新GUI显示图像。
  4. 确保主线程中有事件循环,以显示更新的GUI。

2.代码

发送QImage格式信号

from PyQt5.QtCore import QThread, pyqtSignal 
from PyQt5.QtGui import QImage
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel

class ImgThread(QThread):
    #自定义信号声明
    # 使用自定义信号和UI主线程通讯,参数是发送信号时附带参数的数据类型,可以是str、int、list、QImage、object、np.ndarray等
    signal = pyqtSignal(QImage)
    
    # 定义一个公共参数path,方便后面主函数的图片地址加载使用
    def __init__(self, path):
        super(WorkThread, self).__init__()
        self.path = path
    
    #run函数是子线程中的操作,线程启动后开始执行(run是官方定义的,不能改成其他的函数名)
    def run(self):
        img = QImage(self.path)
        self.signal.emit(img)
        
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 绑定按钮点击事件
        self.pushButton_2.clicked.connect(self.input_image)
        self.pushButton.clicked.connect(self.output_image)

    # 导入文件处理函数
    def input_image(self):
        source = QFileDialog.getOpenFileName(self, '选取视频或图片', "data/", "Pic File(*.mp4 *.mkv *.avi *.flv "
                                                                       "*.jpg *.png)")
        self.centernet_img_path = source[0]  # 提取文件路径
        jpg = QtGui.QPixmap(self.centernet_img_path).scaled(self.image_in.width(),
                                            self.image_in.height())  # 通过文件路径获取图片文件,并设置图片长宽为label控件的长款
        self.image_in.setPixmap(jpg)  # 在label控件上显示选择的图片

    # 热力图生成并展示
    def output_image(self):
        print('Start clicked.')
        self.img_thread = ImgThread()  #实例化一个线程
        # 将线程thread的信号signal和UI主线程中的槽函数update_img进行连接
        self.img_thread.signal.connect(self.update_img)
        # 启动线程,执行线程类中run函数
        self.img_thread.start()
        
    #接受通过emit传来的img信息,执行相应操作
    def update_img(self, img):
        self.img_label.setPixmap(QPixmap.fromImage(img))
        
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

代码

发送np.ndarray格式信号

from PyQt5.QtCore import QThread, pyqtSignal 
from PyQt5.QtGui import QImage
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel

class ImgThread(QThread):
    #自定义信号声明
    # 使用自定义信号和UI主线程通讯,参数是发送信号时附带参数的数据类型,可以是str、int、list、QImage、object、np.ndarray等
    signal = pyqtSignal(np.ndarray)
    
    # 定义一个公共参数path,方便后面主函数的图片地址加载使用
    def __init__(self, path):
        super(WorkThread, self).__init__()
        self.path = path
    
    #run函数是子线程中的操作,线程启动后开始执行(run是官方定义的,不能改成其他的函数名)
    def run(self):
        data = model(self.path)
        self.signal.emit(data)
        
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 绑定按钮点击事件
        self.pushButton_2.clicked.connect(self.input_image)
        self.pushButton.clicked.connect(self.output_image)

    # 导入文件处理函数
    def input_image(self):
        source = QFileDialog.getOpenFileName(self, '选取视频或图片', "data/", "Pic File(*.mp4 *.mkv *.avi *.flv "
                                                                       "*.jpg *.png)")
        self.centernet_img_path = source[0]  # 提取文件路径
        jpg = QtGui.QPixmap(self.centernet_img_path).scaled(self.image_in.width(),
                                            self.image_in.height())  # 通过文件路径获取图片文件,并设置图片长宽为label控件的长款
        self.image_in.setPixmap(jpg)  # 在label控件上显示选择的图片

    # 热力图生成并展示
    def output_image(self):
        print('Start clicked.')
        self.img_thread = ImgThread()  #实例化一个线程
        # 将线程thread的信号signal和UI主线程中的槽函数update_img进行连接
        self.img_thread.signal.connect(self.update_img)
        # 启动线程,执行线程类中run函数
        self.img_thread.start()
        
    #接受通过emit传来的np.ndarray信息,执行相应操作
    def update_img(self, data):
        img_src = cv2.cvtColor(data, cv2.COLOR_BGR2RGB)
        frame = cv2.resize(img_src, dsize=(int(self.img_label.width()), int(self.img_label.height())), interpolation=cv2.INTER_AREA)
        img = QImage(frame.data, frame.shape[1], frame.shape[0], frame.shape[2] * frame.shape[1],
                     QImage.Format_RGB888)
        self.img_label.setPixmap(QPixmap.fromImage(img))
        
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

3.注意点

  1. 线程中使用QImage加载图片,并发射信号传递QImage对象。
  2. 槽方法中接收QImage对象,使用QPixmap显示在label上。
  3. label需要设置scalContents属性为True,否则图片可能不能完整显示。
  4. 确保主线程有事件循环,否则GUI不能实时更新显示图片。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyQt是一个Python的GUI框架,而OpenCV是一个用于计算机视觉和图像处理的开源库,多线程是一种并发执行任务的方式。结合PyQt和OpenCV进行多线程编程,可以将GUI界面和图像处理分别放在不同的线程中,从而提高程序的响应速度和性能。 在使用PyQt和OpenCV进行多线程编程时,首先需要了解如何创建和管理多线程。可以使用Python的threading库来创建线程,并且结合PyQt的信号与槽机制来实现线程间的通信。在使用OpenCV进行图像处理时,可以将图像处理的任务放在一个独立的线程中,这样就不会阻塞主线程,同时可以保持GUI的流畅性。 另外,需要注意的是在多线程编程过程中要处理好线程之间的数据共享和同步问题,避免出现数据竞争或者多线程冲突的情况。可以使用Python的锁、条件变量或者队列等工具来实现线程间的数据同步和共享。 总之,结合PyQt和OpenCV进行多线程编程可以让程序在图像处理和界面显示之间更加流畅和高效,同时也能提高程序的并发处理能力,对于一些需要实时处理和界面交互的应用场景非常有用。367/5000 示例代码可能如下所示: ```python import sys from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLabel from PyQt5.QtCore import QThread, pyqtSignal import cv2 import numpy as np class ImageProcessor(QThread): update_image = pyqtSignal(np.ndarray) # 自定义信号,用于发送处理后的图像 def __init__(self, image_path): super(ImageProcessor, self).__init__() self.image_path = image_path def run(self): while True: image = cv2.imread(self.image_path) # 在这里进行图像处理的相关操作 processed_image = cv2.flip(image, 1) # 例子中简单地进行了图像翻转 self.update_image.emit(processed_image) # 发送处理后的图像信号 class MainWindow(QWidget): def __init__(self): super(MainWindow, self).__init__() self.init_ui() self.init_thread() def init_ui(self): layout = QVBoxLayout() self.label = QLabel() layout.addWidget(self.label) self.setLayout(layout) def init_thread(self): self.thread = ImageProcessor("image.jpg") self.thread.update_image.connect(self.update_image_label) # 绑定处理后的图像信号到更新界面的槽函数 self.thread.start() def update_image_label(self, image): height, width, channel = image.shape bytesPerLine = 3 * width qImg = QImage(image.data, width, height, bytesPerLine, QImage.Format_RGB888) self.label.setPixmap(QPixmap.fromImage(qImg)) if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) ``` 以上是一个简单的使用PyQt和OpenCV进行多线程图像处理的示例代码,该程序会加载一个图片,然后在另外的线程中进行图像处理(翻转操作),并在界面中实时显示处理后的图像。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值