首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >视频在QVideoWidget中的准确位置

视频在QVideoWidget中的准确位置
EN

Stack Overflow用户
提问于 2022-05-03 22:28:31
回答 1查看 264关注 0票数 0

我有一个定制的媒体播放器,它可以在PyQt的帮助下显示图像和视频。媒体播放器由python中的以下代码实现:

代码语言:javascript
复制
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, 
QLabel, \
QSlider, QStyle, QSizePolicy, QFileDialog
import sys
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtGui import QIcon, QPalette
from PyQt5.QtCore import Qt, QUrl



class Window(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("PyQt5 Media Player")
        self.setGeometry(350, 100, 700, 500)
        self.setWindowIcon(QIcon('player.png'))

        p =self.palette()
        p.setColor(QPalette.Window, Qt.black)
        self.setPalette(p)

        self.init_ui()


        self.show()


     def init_ui(self):

        #create media player object
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)


        #create videowidget object

        videowidget = QVideoWidget()


        #create open button
        openBtn = QPushButton('Open Video')
        openBtn.clicked.connect(self.open_file)



        #create button for playing
        self.playBtn = QPushButton()
        self.playBtn.setEnabled(False)
        self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playBtn.clicked.connect(self.play_video)



        #create slider
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setRange(0,0)
        self.slider.sliderMoved.connect(self.set_position)



        #create label
        self.label = QLabel()
        self.label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)


        #create hbox layout
        hboxLayout = QHBoxLayout()
        hboxLayout.setContentsMargins(0,0,0,0)

        #set widgets to the hbox layout
        hboxLayout.addWidget(openBtn)
        hboxLayout.addWidget(self.playBtn)
        hboxLayout.addWidget(self.slider)



        #create vbox layout
        vboxLayout = QVBoxLayout()
        vboxLayout.addWidget(videowidget)
        vboxLayout.addLayout(hboxLayout)
        vboxLayout.addWidget(self.label)


        self.setLayout(vboxLayout)

        self.mediaPlayer.setVideoOutput(videowidget)


        #media player signals

        self.mediaPlayer.stateChanged.connect(self.mediastate_changed)
        self.mediaPlayer.positionChanged.connect(self.position_changed)
        self.mediaPlayer.durationChanged.connect(self.duration_changed)


    def open_file(self):
        filename, _ = QFileDialog.getOpenFileName(self, "Open Video")

        if filename != '':
            self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(filename)))
            self.playBtn.setEnabled(True)


    def play_video(self):
         if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()

        else:
            self.mediaPlayer.play()


    def mediastate_changed(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playBtn.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPause)

            )

        else:
            self.playBtn.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPlay)
 
            )

    def position_changed(self, position):
         self.slider.setValue(position)


    def duration_changed(self, duration):
         self.slider.setRange(0, duration)


    def set_position(self, position):
         self.mediaPlayer.setPosition(position)


    def handle_errors(self):
        self.playBtn.setEnabled(False)
        self.label.setText("Error: " + self.mediaPlayer.errorString())                          
        app = QApplication(sys.argv)                                                         
        window = Window()                                                     
        sys.exit(app.exec_())    

我想做的是每次播放视频/图像的边缘的x和y坐标,虽然感觉应该很简单,但我真的想不出怎么做。如在图像中显示的那样,每个视频/图像可能有不同的角位置。我唯一能想到的就是获得视频的尺寸,但这是不对的。

代码语言:javascript
复制
    print(videowidget.height())
    print(videowidget.width())                                 
    print(videowidget.x())
    print(videowidget.y())

EN

回答 1

Stack Overflow用户

发布于 2022-08-09 19:42:06

我不确定这是否准确地回答了您的问题,但通过比较视频和小部件的高宽比,我找到了一种解决方案:

代码语言:javascript
复制
class VideoClickWidget(QVideoWidget):

    def __init__(self):
        QVideoWidget.__init__(self)
    
    def mouseReleaseEvent(self, event):
        widget_width = self.frameGeometry().width()
        widget_height = self.frameGeometry().height()
        widget_ratio = widget_width / widget_height

        video_width = self.mediaObject().metaData("Resolution").width()
        video_height = self.mediaObject().metaData("Resolution").height()
        video_ratio = video_width / video_height

        x, y  = event.pos().x(), event.pos().y()

        # It's wider
        if widget_ratio > video_ratio:
            percentage = video_ratio / widget_ratio
            # we know that video occupies $percentage$ of the widget
            dead_zone = int(np.round(widget_width * ((1 - percentage) / 2)))

            new_x = np.clip(x - dead_zone, 0, widget_width - 2 * dead_zone)

            print(new_x, y)



        else:
            percentage = widget_ratio / video_ratio

            dead_zone = int(np.round(widget_height * ((1 - percentage) / 2)))
            new_y = np.clip(y - dead_zone, 0, widget_height - 2 * dead_zone)

            print(x, new_y)

        
        
        super(QVideoWidget, self).mouseReleaseEvent(event)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72106090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档