Может ли другой процесс управлять виджетом pyqt5 в основном процессе при использовании многопроцессорной обработки? - PullRequest
0 голосов
/ 06 апреля 2020

Я работаю над программным обеспечением, которое может воспроизводить несколько видео одновременно и собирать их в одном интерфейсе. В результате существования GIL, который мешает эффективности потоков, я решил использовать один процесс для каждого воспроизводимого видео. Вот мои упрощенные коды.

import multiprocessing as mp
import threading
import cv2
from PyQt5.Qt import *
from PyQt5 import QtWidgets, QtCore
import threading

class Main_UI(QtWidgets.QMainWindow)
       def __init__(self):
          super().__init__()
          self.label_screen1 = QtWidgets.QLabel(self)   # used for display
          self.label_screen2 = QtWidgets.QLabel(self)   # used for display
          self.img_q1=mp.Queue(maxsize=2)      # a queue used as frame channel
          self.img_q2=mp.Queue(maxsize=2)      # a queue used as frame channel
          #create a process to read videos, it sends frames to the queue1
          self.img_fetcher1= mp.Process(target=play,args = (self.img_q1,"xxx/xxx.mp4"))
          self.img_fetcher1.start()
          #create a process to read videos, it sends frames to the queue2
          self.img_fetcher2= mp.Process(target=play,args = (self.img_q2,"yyy/yyy.mp4"))
          self.img_fetcher2.start()

          #create a thread to keep displaying the images received from the queue1 onto the label1
          self.video_thread1 = threading.Thread(target=self.display)
          self.video_thread1.start()
          #create a thread to keep displaying the images received from the queue2 onto the label2
          self.video_thread2 = threading.Thread(target=self.display)
          self.video_thread2.start()

       def display(self):
            while True:
                if not self.result_img_q.empty():
                    show=self.result_img_q.get()
                    showImage = QImage(show.data, show.shape[1], show.shape[0],
                                   QImage.Format_RGB888)  
                    self.label_screen.setScaledContents(True)
                    self.label_screen.setPixmap(QPixmap.fromImage(showImage))   #display on the label




def play(img_q,video_path):     # this method run as a process
    videocap = cv2.VideoCapture(video_path)
    while True:
        flag, frame = videocap.read()
        if flag:   
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  
                time.sleep(0.02)
                img_q.put(frame)            #send the frame to the queue

Код работает нормально ,, но я обнаружил, что скорость не настолько удовлетворительная. Я думаю, это отчасти из-за GIL, 2 потока не могут отображать изображения на ярлыках по отдельности и одновременно, так как один должен ждать другого. Интересно, можно ли отобразить изображение на этикетке напрямую с помощью процесса img_fetcher? Точно так же, как передача общего значения процессу из основного процесса и изменение значения в этом процессе.

Может кто-нибудь сказать, как решить эту проблему? Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...