<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
        博客園  :: 首頁(yè)  :: 新隨筆  :: 聯(lián)系 :: 訂閱 訂閱  :: 管理

      官方例程連接

      # Copyright (C) 2022 The Qt Company Ltd.
      # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
      
      """PySide6 Multimedia player example"""
      
      import sys
      from PySide6.QtCore import QStandardPaths, Qt, Slot
      from PySide6.QtGui import QAction, QIcon, QKeySequence
      from PySide6.QtWidgets import (QApplication, QDialog, QFileDialog,
          QMainWindow, QSlider, QStyle, QToolBar)
      from PySide6.QtMultimedia import (QAudioOutput, QMediaFormat,
                                        QMediaPlayer)
      from PySide6.QtMultimediaWidgets import QVideoWidget

       引用的庫(kù)

      AVI = "video/x-msvideo"  # AVI
      
      
      MP4 = 'video/mp4'

      全局變量

      def get_supported_mime_types():
          result = []
          for f in QMediaFormat().supportedFileFormats(QMediaFormat.Decode):
              mime_type = QMediaFormat(f).mimeType()
              result.append(mime_type.name())
          return result
      

      全局函數(shù)

      class MainWindow(QMainWindow):
      
          def __init__(self):
              super().__init__()

      一般Qt項(xiàng)目都會(huì)設(shè)計(jì)這樣一個(gè)MainWindow的類,方便調(diào)用。然后首先是init函數(shù)的聲明,第一句有點(diǎn)讓人摸不著頭腦。super()是Python的一個(gè)內(nèi)置函數(shù),簡(jiǎn)單來(lái)講作用就是允許調(diào)用父類的屬性。

      更多關(guān)于super()的介紹可以看這兩篇文章

      Python super(self.__class__, self).__init__() 怎樣理解? - 知乎

      http://t.csdn.cn/TcXeb

      
              self._playlist = []  # FIXME 6.3: Replace by QMediaPlaylist?
              self._playlist_index = -1
              self._audio_output = QAudioOutput()
              self._player = QMediaPlayer()
              self._player.setAudioOutput(self._audio_output)
      
              self._player.errorOccurred.connect(self._player_error)

      首先是_playlist方法

      然后是關(guān)于音頻輸出的方法_audio_output和setAudioOutput,由于使用Qt進(jìn)行視頻播放音頻和畫(huà)面是分開(kāi)輸出的,沒(méi)有這個(gè)方法就會(huì)導(dǎo)致打開(kāi)視頻時(shí)沒(méi)有聲音。

      然后是_play方法,用于視頻圖像的輸出。

              tool_bar = QToolBar()
              self.addToolBar(tool_bar)
      
              file_menu = self.menuBar().addMenu("&File")
              icon = QIcon.fromTheme("document-open")
              open_action = QAction(icon, "&Open...", self,
                                    shortcut=QKeySequence.Open, triggered=self.open)
              file_menu.addAction(open_action)
              tool_bar.addAction(open_action)
              icon = QIcon.fromTheme("application-exit")
              exit_action = QAction(icon, "E&xit", self,
                                    shortcut="Ctrl+Q", triggered=self.close)
              file_menu.addAction(exit_action)
      

      接下來(lái)一段程序的作用是繪制圖形界面的菜單欄。本段繪制的是上方菜單欄第一個(gè)選項(xiàng)File的下拉菜單,并配置了事件。

      前兩行的作用是實(shí)例化QToolBar方法,并使用addToolBar方法添加到窗口。需要注意的是此處的toolBar和menuBar是不一樣的。menuBar實(shí)現(xiàn)的效果在窗口標(biāo)題下方一行,而toolBar實(shí)現(xiàn)的在menuBar下方,并且它需要手動(dòng)創(chuàng)建。

      接下來(lái)第三行,顯然是在菜單欄添加File選項(xiàng)。第四行作為一個(gè)局部變量并且在之后被多次賦值,它的目的是作為QAction()的一個(gè)實(shí)參。這樣做的目的我不太清楚,因?yàn)樵谶@里并沒(méi)有自動(dòng)回收之類的問(wèn)題,我試著將第四行直接填入QAction()作為實(shí)參,依然可以完成打開(kāi)文件的功能。

      第五行設(shè)置了按鍵的事件,shortcut配置快捷鍵,triggered配置點(diǎn)擊后調(diào)用的函數(shù)。

      第六和第七行使用addAction方法將open_action這個(gè)事件連接到file_menu和tool_bar兩個(gè)按鍵的,如果配置多個(gè)事件,在按鍵的下拉菜單上將從上到下按照添加的順序顯示。

      之后三行則是設(shè)置下拉菜單的Exit選項(xiàng),方法同上。

              play_menu = self.menuBar().addMenu("&Play")
              style = self.style()
              icon = QIcon.fromTheme("media-playback-start.png",
                                     style.standardIcon(QStyle.SP_MediaPlay))
              self._play_action = tool_bar.addAction(icon, "Play")
              self._play_action.triggered.connect(self._player.play)
              play_menu.addAction(self._play_action)
      
              icon = QIcon.fromTheme("media-skip-backward-symbolic.svg",
                                     style.standardIcon(QStyle.SP_MediaSkipBackward))
              self._previous_action = tool_bar.addAction(icon, "Previous")
              self._previous_action.triggered.connect(self.previous_clicked)
              play_menu.addAction(self._previous_action)
      
              icon = QIcon.fromTheme("media-playback-pause.png",
                                     style.standardIcon(QStyle.SP_MediaPause))
              self._pause_action = tool_bar.addAction(icon, "Pause")
              self._pause_action.triggered.connect(self._player.pause)
              play_menu.addAction(self._pause_action)
      
              icon = QIcon.fromTheme("media-skip-forward-symbolic.svg",
                                     style.standardIcon(QStyle.SP_MediaSkipForward))
              self._next_action = tool_bar.addAction(icon, "Next")
              self._next_action.triggered.connect(self.next_clicked)
              play_menu.addAction(self._next_action)
      
              icon = QIcon.fromTheme("media-playback-stop.png",
                                     style.standardIcon(QStyle.SP_MediaStop))
              self._stop_action = tool_bar.addAction(icon, "Stop")
              self._stop_action.triggered.connect(self._ensure_stopped)
              play_menu.addAction(self._stop_action)

      這段代碼繪制了Play選項(xiàng)及其下拉菜單,用到了Qt的圖標(biāo)類即QIcon

      第一行在菜單欄添加Play選項(xiàng)。第二行實(shí)例化style類,作用是后面繪制下拉菜單的時(shí)候通過(guò)

      style.standardIcon()

      引入Qt內(nèi)置圖標(biāo),參數(shù)可選擇,具體內(nèi)容可以參考這篇博客

      從第四行,可以注意到addAction()被賦值到self._play_action。這個(gè)self._play_action是什么呢?通過(guò)查詢文檔能夠得知這是屬于MainWindow類的方法,與視頻播放功能有關(guān)。另外幾個(gè)播放選項(xiàng)也有類似的兩條語(yǔ)句,一句將按鍵動(dòng)作和圖標(biāo)addAction賦值到self._play_action,一句使用self._play_action.triggered.connect()方法將按鍵關(guān)聯(lián)到視頻播放的動(dòng)作,實(shí)現(xiàn)需要的功能。

      第六行添加到下拉菜單,與File類似。

              self._volume_slider = QSlider()
              self._volume_slider.setOrientation(Qt.Horizontal)
              self._volume_slider.setMinimum(0)
              self._volume_slider.setMaximum(100)
              available_width = self.screen().availableGeometry().width()
              self._volume_slider.setFixedWidth(available_width / 10)
              self._volume_slider.setValue(self._audio_output.volume())
              self._volume_slider.setTickInterval(10)
              self._volume_slider.setTickPosition(QSlider.TicksBelow)
              self._volume_slider.setToolTip("Volume")
              self._volume_slider.valueChanged.connect(self._audio_output.setVolume)
              tool_bar.addWidget(self._volume_slider)
      

      這段代碼用于繪制調(diào)節(jié)音量的滑動(dòng)條,主要使用的QSlider控件在這篇博文當(dāng)中有更詳細(xì)的介紹。

      第二行,setOrientation()函數(shù)用于設(shè)置滑動(dòng)條垂直或是水平繪制,此處設(shè)為水平。

      第三、四行,設(shè)置滑動(dòng)條對(duì)應(yīng)的最大和最小值。

      第五、六行,參考這篇博文,availableGeometry可以返回屏幕的可用幾何圖形大小,是screenGeometry()即窗口相對(duì)于父窗口的幾何形狀的大小的子矩形,在頂層窗口的情況下返回不包括邊框的屏幕大小。這兩行將滑動(dòng)條的長(zhǎng)度設(shè)置為屏幕寬度的十分之一

      第七行將滑動(dòng)條的位置關(guān)聯(lián)到self._audio_output.volume(),也就是音頻的音量大小。

      第八、九行,setTickInterval()用于設(shè)置刻度間隔,參數(shù)10為步長(zhǎng)。setTickPosition()用于設(shè)置指定刻度線相對(duì)于滑塊和用戶操作的位置。

      第十行,setToolTip用于設(shè)定提示,效果如下圖

      第十一行,連接信號(hào)槽設(shè)置音量大小

      第十二行,將控件添加到窗口。注意到之前的按鍵并沒(méi)有這行語(yǔ)句,可能因?yàn)檫@是特殊控件才需要這句?

              about_menu = self.menuBar().addMenu("&About")
              about_qt_act = QAction("About &Qt", self, triggered=qApp.aboutQt)
              about_menu.addAction(about_qt_act)
      

      這部分代碼繪制菜單欄的About按鍵,信號(hào)槽連接到qApp.aboutQt,點(diǎn)擊出現(xiàn)一個(gè)文檔

              self._video_widget = QVideoWidget()
              self.setCentralWidget(self._video_widget)
              self._player.playbackStateChanged.connect(self.update_buttons)
              self._player.setVideoOutput(self._video_widget)
      
              self.update_buttons(self._player.playbackState())
              self._mime_types = []

      這部分代碼繪制最重要的功能即視頻窗口。

      第一行,實(shí)例化QVideoWidget

      第二行,將視頻窗口添加到主窗口的中央

      第三行,playbackStateChanged視頻播放狀態(tài)發(fā)生改變,將update_buttons關(guān)聯(lián)

      第四行,在視頻窗口進(jìn)行視頻的畫(huà)面輸出

      第五行,_mime_types初始化

              def closeEvent(self, event):
              self._ensure_stopped()
              event.accept()

      closeEvent是Qt從窗口接受到關(guān)閉請(qǐng)求時(shí)觸發(fā),此處重寫(xiě)了QWidget中的方法。語(yǔ)句上看應(yīng)該是播放器停止后才能關(guān)閉,防止窗口關(guān)閉后視頻繼續(xù)播放

          @Slot()
          def open(self):
              self._ensure_stopped()
              file_dialog = QFileDialog(self)
      
              is_windows = sys.platform == 'win32'
              if not self._mime_types:
                  self._mime_types = get_supported_mime_types()
                  if (is_windows and AVI not in self._mime_types):
                      self._mime_types.append(AVI)
                  elif MP4 not in self._mime_types:
                      self._mime_types.append(MP4)
      

      第一行,插槽,將函數(shù)注冊(cè)為槽函數(shù),具體的資料比較復(fù)雜,這里不多說(shuō)

      從第二行開(kāi)始聲明open方法,功能與打開(kāi)視頻文件相關(guān)。

      第三行,調(diào)用了自己類當(dāng)中的一個(gè)函數(shù)_ensure_stopped(),確保播放器已停止

      第四行,調(diào)用QFileDialog,可以遍歷文件系統(tǒng)以選擇文件或目錄,在圖形界面當(dāng)中的作用是打開(kāi)一個(gè)文件對(duì)話框

      第五行,sys.platform獲取當(dāng)前系統(tǒng)平臺(tái),判斷是否為windows系統(tǒng)

      第六行,判斷當(dāng)前mime類型列表為空,則執(zhí)行后續(xù)判斷

      第七行,獲取支持的mime類型列表

      第八行以后,將AVI和MP4文件類型添加到mime列表

      
              file_dialog.setMimeTypeFilters(self._mime_types)
      
              default_mimetype = AVI if is_windows else MP4
              if default_mimetype in self._mime_types:
                  file_dialog.selectMimeTypeFilter(default_mimetype)
      
              movies_location = QStandardPaths.writableLocation(QStandardPaths.MoviesLocation)
              file_dialog.setDirectory(movies_location)
              if file_dialog.exec() == QDialog.Accepted:
                  url = file_dialog.selectedUrls()[0]
                  self._playlist.append(url)
                  self._playlist_index = len(self._playlist) - 1
                  self._player.setSource(url)
                  self._player.play()
      

      第一行,從mime類型列表中設(shè)置文件對(duì)話框中使用的過(guò)濾器

      第二到第四行,根據(jù)操作系統(tǒng)是否是windows設(shè)置默認(rèn)mime類型

      第五、六行,從系統(tǒng)獲取默認(rèn)的Movies地址,并設(shè)置為“Open”文件對(duì)話框的起始位置,就是下圖這個(gè)效果

      第七行以后,定義的是用戶選擇文件之后的操作

      第七行,QDialog.Accepted表示槽函數(shù)接收到確認(rèn)信號(hào)

      第八行,獲取用戶選擇的文件的url

      第九行,將url添加到播放列表

      第十行,重寫(xiě)播放列表索引_playlist_index

      第十一、十二行,設(shè)置視頻文件地址并開(kāi)始播放,_player是視頻畫(huà)面的播放窗口

          @Slot()
          def _ensure_stopped(self):
              if self._player.playbackState() != QMediaPlayer.StoppedState:
                  self._player.stop()
      

       這段代碼定義的函數(shù)作用是確保播放器已經(jīng)停止,如果當(dāng)前播放器狀態(tài)不是停止?fàn)顟B(tài),則停止播放。

          @Slot()
          def previous_clicked(self):
              # Go to previous track if we are within the first 5 seconds of playback
              # Otherwise, seek to the beginning.
              if self._player.position() <= 5000 and self._playlist_index > 0:
                  self._playlist_index -= 1
                  self._playlist.previous()
                  self._player.setSource(self._playlist[self._playlist_index])
              else:
                  self._player.setPosition(0)
      

      這段代碼定義了Previous鍵關(guān)聯(lián)的事件,如果當(dāng)前播放位置小于等于5秒,并且當(dāng)前播放列表中有上一首歌曲,則播放列表索引-1,開(kāi)始播放上一部視頻,否則將播放位置設(shè)置為0。

          @Slot()
          def next_clicked(self):
              if self._playlist_index < len(self._playlist) - 1:
                  self._playlist_index += 1
                  self._player.setSource(self._playlist[self._playlist_index])
      

      這段代碼定義了Next鍵關(guān)聯(lián)的事件,同樣和_playlist_index的操作有關(guān)。

          @Slot("QMediaPlayer::PlaybackState")
          def update_buttons(self, state):
              media_count = len(self._playlist)
              self._play_action.setEnabled(media_count > 0
                  and state != QMediaPlayer.PlayingState)
              self._pause_action.setEnabled(state == QMediaPlayer.PlayingState)
              self._stop_action.setEnabled(state != QMediaPlayer.StoppedState)
              self._previous_action.setEnabled(self._player.position() > 0)
              self._next_action.setEnabled(media_count > 1)
      

      例程GUI沒(méi)有這樣一個(gè)“更新按鈕”,這段函數(shù)的作用是更新播放相關(guān)按鍵的可用狀態(tài)

      第四、五行,如果播放列表中有媒體文件且播放器不在播放狀態(tài),則啟用播放按鈕,否則禁用播放按鈕

      第六行,如果播放器在播放狀態(tài),則啟用暫停按鈕,否則禁用暫停按鈕

      第七行,播放器不在停止?fàn)顟B(tài),則啟用停止按鈕,否則禁用停止按鈕

      第八、九行同理

          def show_status_message(self, message):
              self.statusBar().showMessage(message, 5000)
      

      在狀態(tài)欄中顯示一條消息,5秒后消失。

          @Slot("QMediaPlayer::Error", str)
          def _player_error(self, error, error_string):
              print(error_string, file=sys.stderr)
              self.show_status_message(error_string)
      

      處理播放器發(fā)生錯(cuò)誤的情況。將錯(cuò)誤信息輸出到終端,并在狀態(tài)欄中顯示錯(cuò)誤消息。

      if __name__ == '__main__':
          app = QApplication(sys.argv)
          main_win = MainWindow()
          available_geometry = main_win.screen().availableGeometry()
          main_win.resize(available_geometry.width() / 3,
                          available_geometry.height() / 2)
          main_win.show()
          sys.exit(app.exec())

      這部分是主函數(shù)。

      第五、六行,調(diào)整主窗口的高度和寬度

      主站蜘蛛池模板: 精品无码三级在线观看视频| 性色av一区二区三区精品| 少妇愉情理伦片丰满丰满午夜 | 国产精品久久久久久久网| 老司机亚洲精品一区二区| 久久午夜色播影院| 久久精品无码免费不卡| 国产无遮挡猛进猛出免费| 国产成人MV视频在线观看| 国产一区二区三区在线观看免费| 国产人妻人伦精品婷婷| 亚洲日本精品一区二区| 亚洲国产精品久久久久婷婷老年| 亚洲精品综合网二三区| 爱啪啪av导航| 国产玖玖玖玖精品电影| 婷婷99视频精品全部在线观看| 桃源县| 一级女性全黄久久生活片| 精品一区二区免费不卡| 河曲县| 亚洲午夜香蕉久久精品| 日韩欧美人妻一区二区三区| 91亚洲国产成人久久精品| 无码精品人妻一区二区三区中| 免费现黄频在线观看国产| 国产成年女人特黄特色大片免费| 亚洲中文无码手机永久| 国内精品亚洲成av人片| 浠水县| 制服丝袜美腿一区二区| 成人综合婷婷国产精品久久蜜臀 | 亚洲日本精品国产第一区| 正宁县| 和黑人中出一区二区三区| 夜爽8888视频在线观看| 久久成人伊人欧洲精品| 国语精品国内自产视频| 国产suv精品一区二区五| 亚洲一区二区三区啪啪| 偷拍精品一区二区三区|