PyQt QGraphicsView 大小与 QGraphicsVideoItem 相同

问题描述 投票:0回答:1

我试图使视图与视频大小相同,同时允许其调整大小以填充可用区域,我不确定我通过设置最大大小是否正确,但它确实有效,问题是视频不会以尽可能高的尺寸开始,我必须不断调整窗口大小才能使其可见。

我想要实现的目标的一个很好的例子是像 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_())



python qt pyqt qgraphicsview qgraphicsscene
1个回答
0
投票

设置场景矩形不会使位于场景矩形之外的项目消失。正如文档所解释的那样

“[场景的边界矩形]主要由 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()
© www.soinside.com 2019 - 2024. All rights reserved.