是否可以在不同的线程上启动 PyQt5 媒体播放器并仍然与之交互?

问题描述 投票:0回答:0

对于一个项目,我正在构建一个 PyQt5 媒体播放器。我希望能够通过将新 url 排入我的主线程和媒体播放器之间的共享队列来在我的媒体播放器中播放新视频。我现在使用的代码如下:

from PyQt5.QtWidgets import QWidget, QVBoxLayout
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtCore import QUrl

import threading
import time

class MediaPlayer(QWidget, threading.Thread):
    def __init__(self, queue, url_first_media):
        super().__init__()
        
        # Instantiate queue
        self.queue = queue

        # Create URL
        self.url = QUrl.fromLocalFile(url_first_media)

        # Set window title
        self.setWindowTitle("Media Player")

        # Init UI
        self.__init_ui()

        # Play initial video
        self.media_player.setMedia(QMediaContent(self.url))
        self.media_player.play()

        # Show maximized
        self.showMaximized()

    def __init_ui(self):
        INITIALIZE UI, left out to not make this code block too bulky.

    def run(self):
        self.__process_data()

    def __process_data(self):
        terminate = False
        while not terminate:
            if not self.queue.empty():
                url, terminate = self.queue.get()
                self.__change_video(url)
            
            time.sleep(1)

    def __change_video(self, video_url):
        # Create URL object
        self.url = QUrl.fromLocalFile(video_url)

        # Change playing video
        self.media_player.setMedia(QMediaContent(self.url))

        # Play new video
        self.media_player.play()

我的主线程来自另一个名为 Environment 的类,该类的代码如下。

from media_player import MediaPlayer

import queue

class Environment:
    def __init__(self):
        self.queue = queue.Queue(5)
        self.media_player = MediaPlayer(self.queue, "path")
        self.__start_media_player()

    def __start_media_player(self):
        self.media_player.start()

所以现在,我认为工作正常的只是启动线程。显然媒体播放器没有显示,因为我没有像 PyQt5 文档建议的那样显示它。他们建议适合我班级的代码如下。

import sys
from PyQt5.QtWidgets import QApplication
from media_player import MediaPlayer

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MediaPlayer(queue, "path_to_video")
    window.show()

    sys.exit(app.exec())

我不确定将此代码放入当前结构的何处才能使其正常工作。我想把它放在 run() 中的 self.__process_data() 之后,但恐怕这行不通,因为它前面有一个 while 循环。我想尝试的另一件事是在 Environment 中启动我的线程后将其放置。我也担心这不会起作用,因为我猜显示媒体播放器的循环会锁定我的主线程。有什么解决办法还是我看错了?

我想要实现的主要目标是通过调用 __change_video() 来改变我的 media_player 中播放的视频。我还研究了 PyQt5 的工作线程,但我不希望我的环境线程被破坏,因为我需要它与其他事物交互(所以我不能继续删除/初始化 Environment 对象)。我对多线程和 PyQt5 很陌生,所以非常感谢任何帮助/建议!

python pyqt pyqt5 python-multithreading qmediaplayer
© www.soinside.com 2019 - 2024. All rights reserved.