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

PySide6中如何实现QVideoWidget视频窗口的圆角显示?

解决PySide6中QVideoWidget视频圆角显示问题

你遇到的问题核心在于QMediaPlayer的视频渲染是底层硬件加速输出,直接修改QVideoWidget的形状、叠加上层元素都会被原生渲染层覆盖,而且你代码里额外新建了一个QVideoWidget(screen)作为输出,反而绕开了QT Designer创建的组件,导致样式和层级控制失效。

给你两个可行的解决思路,亲测有效:


方案一:复用QT Designer的video_widget,通过父容器裁剪实现圆角

  1. 在QT Designer中,给你的video_widget套一个父容器(比如QWidget,命名为video_container),把video_widget放在容器内部,调整好大小。
  2. 给父容器设置样式和裁剪属性,让它成为圆角遮罩,视频在容器内部显示,超出圆角的部分会被裁剪掉。

修改后的代码示例:

def play_video(self):
    global player
    # 配置父容器的圆角和裁剪
    self.video_container.setStyleSheet("""
        QWidget#video_container {
            border-radius: 15px;
            background-color: black;
        }
    """)
    self.video_container.setAttribute(QtCore.Qt.WA_TranslucentBackground)
    self.video_container.setContentsMargins(0, 0, 0, 0)
    # 确保video_widget填满容器,没有边距
    self.video_widget.setStyleSheet("background-color: black;")
    self.video_widget.setParent(self.video_container)
    self.video_widget.setGeometry(0, 0, self.video_container.width(), self.video_container.height())
    
    # 初始化媒体播放组件,直接用设计器的video_widget作为输出
    audio = QAudioOutput(self.video_widget)
    player = QMediaPlayer(self.video_widget)
    player.setAudioOutput(audio)
    player.setVideoOutput(self.video_widget)
    player.setSource(QUrl.fromLocalFile('demo.mp4'))
    player.play()

关键说明:

  • 父容器的border-radius是实现圆角的核心,同时开启WA_TranslucentBackground让容器背景透明,只保留圆角边框的遮罩效果。
  • 必须让video_widget完全填满父容器,避免出现缝隙。
  • 不要额外新建QVideoWidget,直接复用设计器生成的组件,这样才能被父容器正确裁剪。

方案二:使用QGraphicsView+QGraphicsVideoItem实现圆角

如果方案一的裁剪效果不够理想,可以用图形视图框架来实现:

  1. 在QT Designer中拖入一个QGraphicsView(命名为video_view)。
  2. 用QGraphicsVideoItem作为视频载体,添加到视图场景中,然后给视图设置圆角样式。

代码示例:

def play_video(self):
    global player, video_item
    # 配置QGraphicsView的圆角
    self.video_view.setStyleSheet("border-radius: 15px; background-color: black;")
    self.video_view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
    self.video_view.setRenderHint(QPainter.Antialiasing)
    
    # 创建视频项并添加到场景
    scene = QGraphicsScene(self.video_view)
    video_item = QGraphicsVideoItem()
    scene.addItem(video_item)
    self.video_view.setScene(scene)
    
    # 初始化媒体播放器
    audio = QAudioOutput(self.video_view)
    player = QMediaPlayer(self.video_view)
    player.setAudioOutput(audio)
    player.setVideoOutput(video_item)
    player.setSource(QUrl.fromLocalFile('demo.mp4'))
    
    # 调整视频项大小适配视图
    player.play()
    video_item.setSize(QSizeF(self.video_view.viewport().size()))

关键说明:

  • QGraphicsVideoItem是基于图形视图的视频渲染组件,更容易被视图的样式和裁剪控制。
  • 播放后调整视频项大小,确保填满视图区域。

为什么你之前的方法无效?

  • 额外创建的screen = QVideoWidget(video_widget)是一个独立的原生渲染窗口,层级高于QT Designer的组件,所以叠加的边框会被它覆盖。
  • QVideoWidget本身的形状修改(比如setMask)对硬件加速的视频渲染无效,因为视频是直接画在底层窗口上的,不受组件形状约束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:48:25