我试图使视图与视频大小相同,同时允许其调整大小以填充可用区域,我不确定我通过设置最大大小是否正确,但它确实有效,问题是视频不会以尽可能高的尺寸开始,我必须不断调整窗口大小才能使其可见。
我想要实现的目标的一个很好的例子是像 Premiere Pro 这样的视频编辑器,其中视频大小决定场景/视图大小。
import sys
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtGui import QResizeEvent, QShowEvent
from PySide6.QtWidgets import *
from PySide6.QtMultimediaWidgets import QGraphicsVideoItem
from PySide6.QtMultimedia import QMediaPlayer, QAudioOutput, QMediaMetaData
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.scene = QGraphicsScene()
self.view = QGraphicsView(self.scene)
self.video_widget = QGraphicsVideoItem()
self.scene.addItem(self.video_widget)
self.mediaPlayer = QMediaPlayer()
self.mediaPlayer.setVideoOutput(self.video_widget)
self.mediaPlayer.setSource(QUrl.fromLocalFile("potrait.mp4"))
self.video_widget.setSize(self.mediaPlayer.videoSink().videoSize())
self.text = QGraphicsTextItem("test")
self.text.setFlags(QGraphicsTextItem.ItemIsSelectable | QGraphicsTextItem.ItemIsMovable |
QGraphicsTextItem.ItemIsFocusable)
font = QFont()
font.setPointSize(100)
self.text.setFont(font)
self.scene.addItem(self.text)
layout = QVBoxLayout(self)
layout.addWidget(self.view)
self.setLayout(layout)
self.view.setScene(self.scene)
self.mediaPlayer.play()
def resizeFunc(self):
# Fit the view in the scene while keeping the aspect ratio
self.view.fitInView(self.scene.sceneRect(), Qt.KeepAspectRatio)
self.scene.setSceneRect(self.video_widget.boundingRect())
self.view.setFrameStyle(0)
# Get the bounding rectangle of the video item in scene coordinates
video_item_rect_scene = self.video_widget.sceneBoundingRect()
# Map the top-left point of the bounding rectangle from scene coordinates to view coordinates
video_item_top_left_view = self.view.mapFromScene(video_item_rect_scene.topLeft())
video_item_width_view = self.view.mapFromScene(video_item_rect_scene.topRight()).x() - video_item_top_left_view.x()
video_item_height_view = self.view.mapFromScene(video_item_rect_scene.bottomLeft()).y() - video_item_top_left_view.y()
# Create a QSizeF object representing the size of the bounding rectangle in view coordinates
video_item_size_view = QSizeF(video_item_width_view, video_item_height_view)
self.view.setMaximumSize(video_item_width_view + 5, video_item_height_view + 5)
print("Size of video item in scene:", video_item_size_view)
def resizeEvent(self, event):
self.resizeFunc()
def showEvent(self, event):
self.resizeFunc()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
设置场景矩形不会使位于场景矩形之外的项目消失。正如文档所解释的那样:
“[场景的边界矩形]主要由 QGraphicsView 用来确定视图的默认可滚动区域,并由 QGraphicsScene 用来管理项目索引”。
一种可能是对项目进行clip绘画,但您需要它的子类:
class SceneClipTextItem(QGraphicsTextItem):
def paint(self, qp, opt, widget=None):
qp.save()
qp.setClipRect(self.scene().sceneRect())
super().paint(qp, opt, widget)
qp.restore()