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

Qt6/PySide6图形元素定位问题:如何实现文字与视频叠加?

QGraphicsItem叠加文字到视频上方的问题解决

问题原因

你遇到的问题核心在于两点:

  • QGraphicsView默认会将场景内容居中显示,视频加载后会处于视图中心,而文字固定在场景(0,0)位置(对应视图顶部),无法实现叠加。
  • 文字与视频的默认显示层级相同,即便位置调整,文字也可能被视频遮挡。

解决方案

以下是两种简洁有效的实现方式:

方式1:将文字设为视频元素的子项(推荐)

把文字Item设置为视频Item的子元素,文字会自动跟随视频的位置、尺寸变化,天然实现叠加效果,还能方便地相对于视频定位文字。

修改后的代码:

import sys
from PySide6 import QtWidgets, QtCore, QtMultimedia, QtMultimediaWidgets

class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        
        view = QtWidgets.QGraphicsView(self)
        # 设置视图对齐方式为左上角,避免场景居中导致的位置偏移
        view.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
        
        # 创建播放器
        player = QtMultimedia.QMediaPlayer(self)
        player.setSource(QtCore.QUrl("https://archive.org/download/SampleVideo1280x7205mb/SampleVideo_1280x720_5mb.mp4"))
        
        video = QtMultimediaWidgets.QGraphicsVideoItem()
        player.setVideoOutput(video)
        
        text = QtWidgets.QGraphicsTextItem("Hello World")
        # 将文字设为视频的子项,实现叠加
        text.setParentItem(video)
        
        scene = QtWidgets.QGraphicsScene()
        scene.addItem(video)
        
        view.setScene(scene)
        view.setFixedSize(800,800)
        player.play()
        player.setLoops(-1)
        
        # 监听视频尺寸变化,动态调整文字到视频中心
        def update_text_pos():
            text.setPos(video.boundingRect().center() - text.boundingRect().center())
        video.boundingRectChanged.connect(update_text_pos)
        
if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    widget = MyWidget()
    widget.resize(800, 800)
    widget.show()

    sys.exit(app.exec())

方式2:手动同步位置与层级

如果不想使用子项,可手动设置文字的Z值确保在视频上方,并同步两者的位置:

import sys
from PySide6 import QtWidgets, QtCore, QtMultimedia, QtMultimediaWidgets

class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        
        view = QtWidgets.QGraphicsView(self)
        view.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
        
        player = QtMultimedia.QMediaPlayer(self)
        player.setSource(QtCore.QUrl("https://archive.org/download/SampleVideo1280x7205mb/SampleVideo_1280x720_5mb.mp4"))
        
        video = QtMultimediaWidgets.QGraphicsVideoItem()
        player.setVideoOutput(video)
        video.setPos(0, 0)  # 固定视频位置
        
        text = QtWidgets.QGraphicsTextItem("Hello World")
        text.setZValue(1)  # 提高文字层级,避免被视频遮挡
        text.setPos(50, 50)  # 设置文字在视频上的位置
        
        scene = QtWidgets.QGraphicsScene()
        scene.addItem(video)
        scene.addItem(text)
        
        view.setScene(scene)
        view.setFixedSize(800,800)
        player.play()
        player.setLoops(-1)
        
if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    widget = MyWidget()
    widget.resize(800, 800)
    widget.show()

    sys.exit(app.exec())

关键说明

  • setZValue():控制Item的显示层级,值越高越靠上,确保文字不会被视频遮挡。
  • setParentItem():将文字绑定到视频,实现跟随式叠加,适合需要文字随视频移动的场景。
  • view.setAlignment():关闭视图的居中对齐,让场景的(0,0)对应视图左上角,避免位置偏移混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:01:10