Полупрозрачный QWebEngineView перед виджетом libvl c в PySide2 (Qt5) - PullRequest
0 голосов
/ 03 августа 2020

Я использую python -vl c (официальные привязки libvl c) , чтобы встроить VL C -player в мой PySide2 (официальные привязки Qt5 для Python) application.

Пока работает хорошо. Моя реальная цель, однако, состоит в том, чтобы наложить на виджет VL C прозрачный веб-просмотр (или, точнее, QWebEngineView с прозрачным фоном).

Однако, вопреки моим ожиданиям, фон веб-просмотра кажется просто взять цвет фона моего виджета vl c вместо того, чтобы просто отображать игрока, стоящего за ним.

  • Если я применю цвет фона к моему виджету vl c с помощью PySide2, мой веб-просмотр примет тот же цвет фона.
  • Когда я не устанавливаю цвет фона, мой веб-просмотр будет иметь цвет фона окна по умолчанию

Теперь я полагаю, что мой веб-просмотр равен фактически прозрачный, но он покажет только то, о чем знает сам PySide2 (Qt). Если libvl c встраивает игрока в окно, это «специальное окно плеера» может не находиться в стеке отрисовки Qt.

Отсюда мой вопрос - как мы можем изменить мою часть кода, чтобы прозрачный виджет (например, QWebEngineView) работал с проигрывателем libvl c?

Вот код:

from PySide2.QtCore import Qt, QSize
from PySide2.QtGui import QPalette, QColor
from PySide2.QtWebEngineWidgets import QWebEngineView
from PySide2.QtWidgets import QMainWindow, QApplication, QHBoxLayout, QWidget, QFrame
import vlc

class Player(QMainWindow):
    def __init__(self, master=None):
        QMainWindow.__init__(self, master)
        self.setWindowTitle("CoolPlayer")

        self.init_player()
        self.widget = QWidget(self)
        self.setCentralWidget(self.widget)

        if sys.platform == "darwin":
            from PySide2.QtWidgets import QMacCocoaViewContainer    
            self.video_frame = QMacCocoaViewContainer(0)
        else:
            self.video_frame = QFrame()
        self.video_frame_palette = self.video_frame.palette()
        self.video_frame_palette.setColor(QPalette.Window, QColor(0,0,0))
        self.video_frame.setPalette(self.video_frame_palette)
        self.video_frame.setAutoFillBackground(True)

        self.video_container = QHBoxLayout(self.widget)
        self.video_container.setContentsMargins(0, 0, 0, 0)
        self.video_container.addWidget(self.video_frame)

        self.browser = QWebEngineView(self.widget)
        self.browser.setAttribute(Qt.WA_TranslucentBackground)
        self.browser.setStyleSheet("background: transparent")
        self.browser.page().setBackgroundColor(Qt.transparent)
        self.browser.load("file:///home/me/index.html")


        self.embed_vlc()
    
    def init_player(self):
        self.instance = vlc.Instance("--quiet")
        self.player = self.instance.media_player_new()
    
    def load_mrl(self, mrl):
        self.media = self.instance.media_new(mrl)
        self.player.set_media(self.media)
        self.player.play()
    
    def embed_vlc(self):
        if sys.platform.startswith('linux'):
            self.player.set_xwindow(self.video_frame.winId())
        elif sys.platform == "win32":
            self.player.set_hwnd(self.video_frame.winId())
        elif sys.platform == "darwin":
            self.player.set_nsobject(int(self.video_frame.winId()))
    
    def resizeEvent(self, event):
        self.browser.resize(event.size())
        event.accept()

Подсказка: как насчет помещения QWebEngineView во второе окно Qt без рамки, которое является верхним уровнем окна проигрывателя (= главным) и всегда меняет размер вместе с ним? Таким образом, мы делаем его постоянно плавающим над окном плеера, но оставляем прозрачность диспетчеру окон. Это также решило бы мой вопрос, но его нужно было бы точно настроить, чтобы вести себя как QWidget, а не в реальном окне верхнего уровня (например, всегда находиться перед главным окном, нет записи на панели задач, минимизировать / максимизировать, когда главное окно свернуто / развернуть, изменить размер в главном окне)

...