You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt:如何更好实现QGraphicsView与QVideoWidget的全屏/还原功能?

多媒体查看器全屏与还原功能实现方案

我正在为多媒体查看器程序实现全屏与还原功能,参考相关论坛帖子后,编写了如下最小可复现示例(实现/还原全屏的核心代码位于Stack类keyPressEvent中的elif event.key() == qtc.Qt.Key.Key_F...代码块):

from __future__ import annotations

from PySide6 import QtCore as qtc
from PySide6 import QtGui as qtg
from PySide6 import QtMultimedia as qtm
from PySide6 import QtMultimediaWidgets as qtmw
from PySide6 import QtWidgets as qtw

image_path = ""
video_path = ""


class Stack(qtw.QStackedWidget):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self._full_screen_widget = None

    def keyPressEvent(self, event: qtg.QKeyEvent) -> None:
        if event.key() == qtc.Qt.Key.Key_N:
            if not self._full_screen_widget:
                if self.currentWidget() == video:
                    self.currentWidget().stop()
                    self.currentWidget().setSource("")
                    self.setCurrentWidget(graphics)
                elif self.currentWidget() == graphics:
                    video.play()
                    self.setCurrentWidget(video)
        elif (
            event.key() == qtc.Qt.Key.Key_F
            and event.modifiers() == qtc.Qt.KeyboardModifier.NoModifier
        ):
            if self._full_screen_widget:
                self._full_screen_widget.showNormal()
                self._full_screen_widget.setWindowFlags(
                    self._full_screen_widget._backup_window_flags
                )
                self._full_screen_widget.setParent(self)
                self.addWidget(self._full_screen_widget)
                self.setCurrentWidget(self._full_screen_widget)
                self._full_screen_widget.setFocus(qtc.Qt.FocusReason.OtherFocusReason)
                self._full_screen_widget = None
            else:
                self._full_screen_widget = self.currentWidget()
                self.removeWidget(self._full_screen_widget)
                self._full_screen_widget.setWindowFlag(qtc.Qt.WindowType.Window)
                self._full_screen_widget.showFullScreen()
        else:
            super().keyPressEvent(event)
            return
        event.accept()
        return


class Graphics(qtw.QGraphicsView):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self._backup_window_flags = self.windowFlags()
        self._scene = qtw.QGraphicsScene()
        self._pixmap_item = qtw.QGraphicsPixmapItem()
        self._pixmap_item.setPixmap(qtg.QPixmap(image_path))
        self._scene.addItem(self._pixmap_item)
        self.setScene(self._scene)

    def keyPressEvent(self, event: qtg.QKeyEvent):
        if event.key() == qtc.Qt.Key.Key_F:
            qtc.QCoreApplication.sendEvent(stack, event)
            event.accept()
            return
        super().keyPressEvent(event)
        return


class Video(qtmw.QVideoWidget):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self._backup_window_flags = self.windowFlags()
        loop = qtc.QEventLoop()
        self._media_player = qtm.QMediaPlayer()
        self._media_player.mediaStatusChanged.connect(loop.exit)
        self._media_player.setVideoOutput(self)
        self._media_player.setSource(video_path)
        loop.exec()

    def play(self):
        self._media_player.play()

    def stop(self):
        self._media_player.stop()

    def setSource(self, source: str):
        self._media_player.setSource(source)

    def keyPressEvent(self, event: qtg.QKeyEvent):
        if event.key() == qtc.Qt.Key.Key_F:
            qtc.QCoreApplication.sendEvent(stack, event)
            event.accept()
            return
        super().keyPressEvent(event)
        return


app = qtw.QApplication()

mw = qtw.QMainWindow()
stack = Stack(parent=mw)
graphics = Graphics(parent=stack)
video = Video(parent=stack)
mw.setCentralWidget(stack)
stack.addWidget(graphics)
stack.addWidget(video)
stack.setCurrentWidget(graphics)
mw.show()

app.exec()

之所以不直接全屏主窗口,是因为实际程序的GUI包含其他元素,主窗口全屏会显示图形/视频组件之外的内容。


内容的提问来源于stack exchange,提问作者Neat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:15:43