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不能实时更新显示图片。

你可能感兴趣的:(qt,开发语言)