PySide6中如何实现QVideoWidget视频窗口的圆角显示?
解决PySide6中QVideoWidget视频圆角显示问题
你遇到的问题核心在于QMediaPlayer的视频渲染是底层硬件加速输出,直接修改QVideoWidget的形状、叠加上层元素都会被原生渲染层覆盖,而且你代码里额外新建了一个QVideoWidget(screen)作为输出,反而绕开了QT Designer创建的组件,导致样式和层级控制失效。
给你两个可行的解决思路,亲测有效:
方案一:复用QT Designer的video_widget,通过父容器裁剪实现圆角
- 在QT Designer中,给你的
video_widget套一个父容器(比如QWidget,命名为video_container),把video_widget放在容器内部,调整好大小。 - 给父容器设置样式和裁剪属性,让它成为圆角遮罩,视频在容器内部显示,超出圆角的部分会被裁剪掉。
修改后的代码示例:
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实现圆角
如果方案一的裁剪效果不够理想,可以用图形视图框架来实现:
- 在QT Designer中拖入一个QGraphicsView(命名为
video_view)。 - 用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
相关产品推荐
相关产品推荐

