class VideoPlayer(QtWidgets.QWidget): def __init__(self, url: str): super(VideoPlayer, self).__init__() self.player = QMediaPlayer() QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.playlist = QMediaPlaylist(self.player) self.playlist.addMedia(QUrl(url)) self.video_widget = QVideoWidget() self.player.setVideoOutput(self.video_widget) self.playlist.setCurrentIndex(0) self.player.setPlaylist(self.playlist) self.layout = QtWidgets.QVBoxLayout() self.layout.addWidget(self.video_widget) self.setLayout(self.layout) self.player.play() QApplication.restoreOverrideCursor() def mousePressEvent(self, event): if self.player.state() == QMediaPlayer.PausedState: self.player. play() else: self.player.pause()
class MainWindow(QMainWindow): def __init__(self): global pixmapDict, specialDescriptionDict super(MainWindow, self).__init__() self.ui = Ui_pipboy() self.ui.setupUi(self) self.ui.chartContainer.setContentsMargins(0, 0, 0, 0) self.anim = QTimeLine(20000, self) self.anim.setFrameRange(0, 500) self.anim.setLoopCount(0) self.anim.setUpdateInterval(16) self.anim.frameChanged[int].connect( self.ui.perks_description.verticalScrollBar().setValue) self.anim.frameChanged[int].connect( self.ui.aid_effect_label.verticalScrollBar().setValue) self.anim.frameChanged[int].connect( self.ui.data_description.verticalScrollBar().setValue) #self.anim2 = QPropertyAnimation(self.ui.main_tab, b"pos") #self.anim2.setEasingCurve(QEasingCurve.OutBounce) #self.anim2.setDuration(2000) #self.anim2.setStartValue(QPoint(10, -400)) #self.anim2.setEndValue(QPoint(10, 0)) #self.anim2.start() self.random = QRandomGenerator.global_() self.ui.stat_tab.setFocus() self.ui.stat_tab.currentChanged.connect(self.shift) self.ui.stat_tab.installEventFilter(self) self.ui.inv_tab.installEventFilter(self) self.ui.special_list.installEventFilter(self) self.ui.perks_list.installEventFilter(self) self.ui.test_list.installEventFilter(self) self.ui.apparel_list.installEventFilter(self) self.ui.aid_list.installEventFilter(self) self.ui.ammo_list.installEventFilter(self) self.ui.data_list.installEventFilter(self) self.ui.radio_list.installEventFilter(self) self.ui.main_img.setPixmap(description.main_img_pixmap) self.ui.special_image.setPixmap(description.pixmapDict.get(0)) self.ui.perks_image.setPixmap(description.pixmatPerksDict.get(0)) self.ui.weapon_image.setPixmap(description.pixmapWeaponDict.get(0)) self.ui.apparel_image.setPixmap(description.pixmapWeaponDict.get(0)) self.ui.aid_image.setPixmap(description.pixmapAidDict.get(0)) self.ui.ammo_image.setPixmap(description.pixmapAmmoDict.get(0)) lay = QVBoxLayout(self.ui.chartContainer) lay.setContentsMargins(0, 0, 0, 0) self.chartview = QtCharts.QChartView() self.chartview.setContentsMargins(0, 0, 0, 0) lay.addWidget(self.chartview) self.chart = QtCharts.QChart() self.chart.legend().hide() self.chart.setAnimationOptions(QtCharts.QChart.SeriesAnimations) self.series = QtCharts.QLineSeries() self.pen = QPen(QColor(119, 251, 81, 255)) self.pen.setWidth(3) self.pen.setJoinStyle(Qt.RoundJoin) self.series.setPen(self.pen) backgroundGradient = QLinearGradient(QPointF(100, 100), QPointF(200, 200)) backgroundGradient.setColorAt(0, QColor(0, 0, 0, 255)) backgroundGradient.setColorAt(1, QColor(0, 0, 0, 255)) self.chart.setBackgroundBrush(backgroundGradient) self.chart.setPlotAreaBackgroundBrush(backgroundGradient) self.chart.addSeries(self.series) self.chart.createDefaultAxes() self.chart.axisX(self.series).setVisible(False) self.chart.axisY(self.series).setVisible(False) self.chart.axisY(self.series).setRange(0, 100) self.chartview.setChart(self.chart) self.play = False self.player = QMediaPlayer() self.playlistFalloutNewVegas = QMediaPlaylist(self.player) self.playlistFalloutNewVegas.addMedia( QMediaContent(description.falooutNewVegas)) self.playlistFalloutNewVegas.setCurrentIndex(1) self.playListMohaveMusic = QMediaPlaylist(self.player) for url in description.mohaveMusic: self.playListMohaveMusic.addMedia(QMediaContent(url)) self.playListMohaveMusic.setCurrentIndex(1) self.playlisNewVegas = QMediaPlaylist(self.player) for url in description.newVegas: self.playlisNewVegas.addMedia(QMediaContent(url)) self.playlisNewVegas.setCurrentIndex(1) self.playlistDict = { 0: self.playlistFalloutNewVegas, 1: self.playListMohaveMusic, 2: self.playlisNewVegas } def append_data_and_plot(self, d): """Append and update the plot""" num, m = d ax1 = self.chart.axisX(self.series) xmin = xmax = num step = 100 for p in self.series.pointsVector()[-step:]: xmin = min(p.x(), xmin) xmax = max(p.x(), xmax) xmin = max(0, xmax - step) ax1.setMin(xmin) ax1.setMax(xmax) self.series.append(QPointF(num, m)) def eventFilter(self, obj, event): if event.type() == QEvent.KeyPress: #print(obj) if event.key() == 49: self.ui.main_tab.setCurrentIndex(1) self.ui.stat_tab.setFocus() #self.ui.hp_head.setValue(self.random.bounded(50, 100)) #self.ui.hp_left_arm.setValue(self.random.bounded(50, 100)) #self.ui.hp_right_arm.setValue(self.random.bounded(50, 100)) #self.ui.hp_left_leg.setValue(self.random.bounded(50, 100)) #self.ui.hp_right_leg.setValue(self.random.bounded(50, 100)) #self.ui.hp_body.setValue(self.random.bounded(50, 100)) return True elif event.key() == 50: self.ui.main_tab.setCurrentIndex(2) self.ui.inv_tab.setFocus() return True elif event.key() == 51: self.ui.main_tab.setCurrentIndex(3) self.ui.data_list.setFocus() self.ui.data_list.setCurrentRow(0) return True elif event.key() == 52: self.ui.main_tab.setCurrentIndex(4) return True elif event.key() == 53: self.ui.main_tab.setCurrentIndex(5) self.ui.radio_list.setFocus() self.ui.radio_list.setCurrentRow(0) return True elif event.key() == 54: print(QApplication.focusWidget()) return True #focus from stat_tab to special_list elif (obj == self.ui.stat_tab) and (self.ui.stat_tab.currentIndex() == 1) and (event.key() == 47): self.ui.special_list.setFocus() self.ui.special_list.setCurrentRow(0) self.ui.special_image.setPixmap(description.pixmapDict.get(0)) self.ui.special_description.setText( description.specialDescriptionDict.get(0)) return True # elif (obj == self.ui.special_list) and (event.key() == 16777236): self.ui.special_list.setCurrentRow( self.ui.special_list.currentRow() + 1) if (self.ui.special_list.currentRow() == -1): self.ui.special_list.setCurrentRow(0) self.ui.special_list.scrollToItem( self.ui.special_list.currentItem()) self.ui.special_image.setPixmap( description.pixmapDict.get( self.ui.special_list.currentRow())) self.ui.special_description.setText( description.specialDescriptionDict.get( self.ui.special_list.currentRow())) elif (obj == self.ui.special_list) and (event.key() == 16777234): self.ui.special_list.setCurrentRow( self.ui.special_list.currentRow() - 1) if (self.ui.special_list.currentRow() == -1): self.ui.special_list.setCurrentRow(0) self.ui.special_list.scrollToItem( self.ui.special_list.currentItem()) self.ui.special_image.setPixmap( description.pixmapDict.get( self.ui.special_list.currentRow())) self.ui.special_description.setText( description.specialDescriptionDict.get( self.ui.special_list.currentRow())) #focus from special_list to stat_tab elif (obj == self.ui.special_list) and (event.key() == 47): self.ui.special_list.setCurrentRow(-1) self.ui.stat_tab.setFocus() return True # focus from stat_tab to perks_list elif (obj == self.ui.stat_tab) and (self.ui.stat_tab.currentIndex() == 2) and (event.key() == 47): self.ui.perks_list.setFocus() self.ui.perks_list.setCurrentRow(0) self.anim.setCurrentTime(0) self.anim.start() elif (obj == self.ui.perks_list) and (event.key() == 16777236): self.ui.perks_list.setCurrentRow( self.ui.perks_list.currentRow() + 1) if (self.ui.perks_list.currentRow() == -1): self.ui.perks_list.setCurrentRow(0) self.ui.perks_list.scrollToItem( self.ui.perks_list.currentItem()) self.ui.perks_image.setPixmap( description.pixmatPerksDict.get( self.ui.perks_list.currentRow())) self.ui.perks_description.setText( description.perksDescriptionDict.get( self.ui.perks_list.currentRow())) self.anim.stop() self.anim.setCurrentTime(0) self.anim.start() elif (obj == self.ui.perks_list) and (event.key() == 16777234): self.ui.perks_list.setCurrentRow( self.ui.perks_list.currentRow() - 1) if (self.ui.perks_list.currentRow() == -1): self.ui.perks_list.setCurrentRow(0) self.ui.perks_list.scrollToItem( self.ui.perks_list.currentItem()) self.ui.perks_image.setPixmap( description.pixmatPerksDict.get( self.ui.perks_list.currentRow())) self.ui.perks_description.setText( description.perksDescriptionDict.get( self.ui.perks_list.currentRow())) self.anim.stop() self.anim.setCurrentTime(0) self.anim.start() #focus from perks_list to stat_tab elif (obj == self.ui.perks_list) and (event.key() == 47): self.ui.perks_list.setCurrentRow(-1) self.ui.stat_tab.setFocus() self.anim.stop() return True #/------------------------------------------------INV-WEAPON--------------------------------------------------/ elif (obj == self.ui.inv_tab) and (self.ui.inv_tab.currentIndex() == 0) and (event.key() == 47): self.ui.test_list.setFocus() self.ui.test_list.setCurrentRow(0) return True elif (obj == self.ui.test_list) and (event.key() == 47): self.ui.test_list.setCurrentRow(-1) self.ui.inv_tab.setFocus() return True elif (obj == self.ui.test_list) and (event.key() == 16777236): self.ui.test_list.setCurrentRow( self.ui.test_list.currentRow() + 1) if (self.ui.test_list.currentRow() == -1): self.ui.test_list.setCurrentRow(0) self.ui.test_list.scrollToItem(self.ui.test_list.currentItem()) self.ui.weapon_image.setPixmap( description.pixmapWeaponDict.get( self.ui.test_list.currentRow())) self.ui.w_damage_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[0]) self.ui.w_weight_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[1]) self.ui.w_cost_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[2]) self.ui.w_durability_PB.setValue(self.random.bounded(20, 100)) self.ui.w_ammo_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[3]) self.ui.w_effect_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[4]) elif (obj == self.ui.test_list) and (event.key() == 16777234): self.ui.test_list.setCurrentRow( self.ui.test_list.currentRow() - 1) if (self.ui.test_list.currentRow() == -1): self.ui.test_list.setCurrentRow(0) self.ui.test_list.scrollToItem(self.ui.test_list.currentItem()) self.ui.weapon_image.setPixmap( description.pixmapWeaponDict.get( self.ui.test_list.currentRow())) self.ui.w_damage_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[0]) self.ui.w_weight_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[1]) self.ui.w_cost_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[2]) self.ui.w_durability_PB.setValue(self.random.bounded(20, 100)) self.ui.w_ammo_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[3]) self.ui.w_effect_label.setText( description.weaponDescriptionDict.get( self.ui.test_list.currentRow())[4]) #/------------------------------------------------INV-APPAREL--------------------------------------------------/ elif (obj == self.ui.inv_tab) and (self.ui.inv_tab.currentIndex() == 1) and (event.key() == 47): self.ui.apparel_list.setFocus() self.ui.apparel_list.setCurrentRow(0) return True elif (obj == self.ui.apparel_list) and (event.key() == 47): self.ui.apparel_list.setCurrentRow(-1) self.ui.inv_tab.setFocus() return True elif (obj == self.ui.apparel_list) and (event.key() == 16777236): self.ui.apparel_list.setCurrentRow( self.ui.apparel_list.currentRow() + 1) if (self.ui.apparel_list.currentRow() == -1): self.ui.apparel_list.setCurrentRow(0) self.ui.apparel_list.scrollToItem( self.ui.apparel_list.currentItem()) self.ui.apparel_image.setPixmap( description.pixmapClothesDict.get( self.ui.apparel_list.currentRow())) self.ui.a_damage_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[0]) self.ui.a_weight_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[1]) self.ui.a_cost_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[2]) self.ui.a_durability_PB.setValue(self.random.bounded(0, 100)) self.ui.a_type_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[3]) self.ui.a_effect_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[4]) elif (obj == self.ui.apparel_list) and (event.key() == 16777234): self.ui.apparel_list.setCurrentRow( self.ui.apparel_list.currentRow() - 1) if (self.ui.apparel_list.currentRow() == -1): self.ui.apparel_list.setCurrentRow(0) self.ui.apparel_list.scrollToItem( self.ui.apparel_list.currentItem()) self.ui.apparel_image.setPixmap( description.pixmapClothesDict.get( self.ui.apparel_list.currentRow())) self.ui.a_damage_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[0]) self.ui.a_weight_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[1]) self.ui.a_cost_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[2]) self.ui.a_durability_PB.setValue(self.random.bounded(0, 100)) self.ui.a_type_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[3]) self.ui.a_effect_label.setText( description.clothesDescriptionDict.get( self.ui.apparel_list.currentRow())[4]) #/------------------------------------------------INV-AID--------------------------------------------------/ elif (obj == self.ui.inv_tab) and (self.ui.inv_tab.currentIndex() == 2) and (event.key() == 47): self.ui.aid_list.setFocus() self.ui.aid_list.setCurrentRow(0) return True elif (obj == self.ui.aid_list) and (event.key() == 47): self.ui.aid_list.setCurrentRow(-1) self.ui.inv_tab.setFocus() return True elif (obj == self.ui.aid_list) and (event.key() == 16777236): self.ui.aid_list.setCurrentRow(self.ui.aid_list.currentRow() + 1) if (self.ui.aid_list.currentRow() == -1): self.ui.aid_list.setCurrentRow(0) self.ui.aid_list.scrollToItem(self.ui.aid_list.currentItem()) self.ui.aid_image.setPixmap( description.pixmapAidDict.get( self.ui.aid_list.currentRow())) self.ui.aid_weight_label.setText( description.aidDescriptionDict.get( self.ui.aid_list.currentRow())[0]) self.ui.aid_cost_label.setText( description.aidDescriptionDict.get( self.ui.aid_list.currentRow())[1]) self.ui.aid_effect_label.setText( description.aidDescriptionDict.get( self.ui.aid_list.currentRow())[2]) self.anim.stop() self.anim.setCurrentTime(0) self.anim.start() elif (obj == self.ui.aid_list) and (event.key() == 16777234): self.ui.aid_list.setCurrentRow(self.ui.aid_list.currentRow() - 1) if (self.ui.aid_list.currentRow() == -1): self.ui.aid_list.setCurrentRow(0) self.ui.aid_list.scrollToItem(self.ui.aid_list.currentItem()) self.ui.aid_image.setPixmap( description.pixmapAidDict.get( self.ui.aid_list.currentRow())) self.ui.aid_weight_label.setText( description.aidDescriptionDict.get( self.ui.aid_list.currentRow())[0]) self.ui.aid_cost_label.setText( description.aidDescriptionDict.get( self.ui.aid_list.currentRow())[1]) self.ui.aid_effect_label.setText( description.aidDescriptionDict.get( self.ui.aid_list.currentRow())[2]) self.anim.stop() self.anim.setCurrentTime(0) self.anim.start() #/------------------------------------------------INV-AMMO--------------------------------------------------/ elif (obj == self.ui.inv_tab) and (self.ui.inv_tab.currentIndex() == 3) and (event.key() == 47): self.ui.ammo_list.setFocus() self.ui.ammo_list.setCurrentRow(0) return True elif (obj == self.ui.ammo_list) and (event.key() == 47): self.ui.ammo_list.setCurrentRow(-1) self.ui.inv_tab.setFocus() return True elif (obj == self.ui.ammo_list) and (event.key() == 16777236): self.ui.ammo_list.setCurrentRow( self.ui.ammo_list.currentRow() + 1) if (self.ui.ammo_list.currentRow() == -1): self.ui.ammo_list.setCurrentRow(0) self.ui.ammo_list.scrollToItem(self.ui.ammo_list.currentItem()) self.ui.ammo_image.setPixmap( description.pixmapAmmoDict.get( self.ui.ammo_list.currentRow())) self.ui.ammo_weight_label.setText( description.ammoDescriptionDict.get( self.ui.ammo_list.currentRow())[0]) self.ui.ammo_cost_label.setText( description.ammoDescriptionDict.get( self.ui.ammo_list.currentRow())[1]) elif (obj == self.ui.ammo_list) and (event.key() == 16777234): self.ui.ammo_list.setCurrentRow( self.ui.ammo_list.currentRow() - 1) if (self.ui.ammo_list.currentRow() == -1): self.ui.ammo_list.setCurrentRow(0) self.ui.ammo_list.scrollToItem(self.ui.ammo_list.currentItem()) self.ui.ammo_image.setPixmap( description.pixmapAmmoDict.get( self.ui.ammo_list.currentRow())) self.ui.ammo_weight_label.setText( description.ammoDescriptionDict.get( self.ui.ammo_list.currentRow())[0]) self.ui.ammo_cost_label.setText( description.ammoDescriptionDict.get( self.ui.ammo_list.currentRow())[1]) #/------------------------------------------------DATA--------------------------------------------------/ elif (obj == self.ui.data_list) and (event.key() == 16777236): self.ui.data_list.setCurrentRow( self.ui.data_list.currentRow() + 1) if (self.ui.data_list.currentRow() == -1): self.ui.data_list.setCurrentRow(0) self.ui.data_list.scrollToItem(self.ui.data_list.currentItem()) self.ui.data_description.setText( description.questDescriptionDict.get( self.ui.data_list.currentRow())) self.anim.stop() self.anim.setCurrentTime(0) self.anim.start() elif (obj == self.ui.data_list) and (event.key() == 16777234): self.ui.data_list.setCurrentRow( self.ui.data_list.currentRow() - 1) if (self.ui.data_list.currentRow() == -1): self.ui.data_list.setCurrentRow(0) self.ui.data_list.scrollToItem(self.ui.data_list.currentItem()) self.ui.data_description.setText( description.questDescriptionDict.get( self.ui.data_list.currentRow())) self.anim.stop() self.anim.setCurrentTime(0) self.anim.start() #/------------------------------------------------RADIO--------------------------------------------------/ elif (obj == self.ui.radio_list) and (event.key() == 16777236): self.ui.radio_list.setCurrentRow( self.ui.radio_list.currentRow() + 1) if (self.ui.radio_list.currentRow() == -1): self.ui.radio_list.setCurrentRow(0) elif (obj == self.ui.radio_list) and (event.key() == 16777234): self.ui.radio_list.setCurrentRow( self.ui.radio_list.currentRow() - 1) if (self.ui.radio_list.currentRow() == -1): self.ui.radio_list.setCurrentRow(0) #self.ui.data_description.setText(description.questDescriptionDict.get(self.ui.radio_list.currentRow())) elif (obj == self.ui.radio_list) and (event.key() == 47): if self.play: self.player.stop() self.play = False else: self.player.setPlaylist( self.playlistDict.get(self.ui.radio_list.currentRow())) self.playListMohaveMusic.setCurrentIndex( self.random.bounded(0, 9) + 1) self.playlisNewVegas.setCurrentIndex( self.random.bounded(0, 10) + 1) self.player.play() self.play = True return True else: #print(event.key()) return True return super(MainWindow, self).eventFilter(obj, event) @Slot() def shift(self): print(self.ui.stat_tab.currentIndex()) index = self.ui.stat_tab.currentIndex() if index == 0: self.ui.stat_tab.setGeometry(0, 0, 904, 380) elif index == 1: self.ui.stat_tab.setGeometry(-108, 0, 904, 380) elif index == 2: self.ui.stat_tab.setGeometry(-214, 0, 904, 380)
class MainWindow(QObject): #class constructor def __init__(self, ui_file, parent=None): #reference to our music player self.music_player = QMediaPlayer() self.music_player.setVolume(50) #call parent QObject constructor super(MainWindow, self).__init__(parent) #load the UI file into Python ui_file = QFile(ui_file) ui_file.open(QFile.ReadOnly) loader = QUiLoader() self.window = loader.load(ui_file) #always remember to close files ui_file.close() #add playlist object self.playlist = QMediaPlaylist() self.playlist.setPlaybackMode(QMediaPlaylist.Sequential) self.music_player.setPlaylist(self.playlist) self.music_player.setNotifyInterval(50) #add a listener to change audio filename displayed #add playlist display object self.playlistDisplay = self.window.findChild(QListWidget, 'PlayListWidget') #self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemOnce) #self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) #self.playlist.setPlaybackMode(QMediaPlaylist.Random) #self.playlist.setPlaybackMode(QMediaPlaylist.Loop) #add event listeners self.add_media_action = self.window.findChild(QAction, 'action_add_media') self.add_media_action.triggered.connect(self.add_media_triggered) self.quit_action = self.window.findChild(QAction, 'action_quit') self.quit_action.triggered.connect(self.quit_action_triggered) self.NextButton = self.window.findChild(QPushButton, 'NextButton') self.NextButton.clicked.connect(self.next_button_clicked) self.PauseButton = self.window.findChild(QPushButton, 'PauseButton') self.PauseButton.clicked.connect(self.pause_button_clicked) #PlayAllRadioButton = self.window.findChild(QRadioButton, 'PlayAllRadioButton') #PlayAllRadioButton.clicked.connect(self.play_all_button_clicked) self.PlayButton = self.window.findChild(QPushButton, 'PlayButton') self.PlayButton.clicked.connect(self.play_button_clicked) self.PreviousButton = self.window.findChild(QPushButton, 'PreviousButton') self.PreviousButton.clicked.connect(self.previous_button_clicked) #ProgressBar = self.window.findChild(QProgressBar, 'ProgressBar') #ProgressBar.valueChanged.connect(self.progress_bar_moved) self.RepeatOnceRadioButton = self.window.findChild( QRadioButton, 'RepeatOnceRadioButton') self.RepeatOnceRadioButton.clicked.connect( self.repeat_once_button_clicked) self.RepeatRadioButton = self.window.findChild(QRadioButton, 'RepeatRadioButton') self.RepeatRadioButton.clicked.connect(self.repeat_button_clicked) #ShuffleCheckBox = self.window.findChild(QCheckBox, 'ShuffleCheckBox') #ShuffleCheckBox.clicked.connect(self.shuffle_checkbox_clicked) #ShuttleSlider = self.window.findChild(QSlider, 'ShuttleSlider') #ShuttleSlider.valueChanged.connect(self.shuttle_slider_moved) self.VolumeSlider = self.window.findChild(QSlider, 'VolumeSlider') self.VolumeSlider.setValue(50) self.VolumeSlider.valueChanged.connect(self.change_volume_level) self.ProgressBar = self.window.findChild(QProgressBar, 'ProgressBar') self.music_player.durationChanged.connect( self.progress_bar_maximum_changed) self.music_player.positionChanged.connect( self.progress_bar_position_changed) #self.Playlist = self.window.findChild(QMediaPlaylist, 'Playlist') #self.Playlist.itemDoubleClicked.connect(self.volume_slider_moved) #show window to user self.window.show() #I referenced code from Jordan Abbott to complete this function def add_media_triggered(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog files, _ = QFileDialog.getOpenFileNames(None, "Select Media Files", "", "All Files (*)", options=options) if files: for file in files: self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(file))) self.playlistDisplay.addItem(os.path.basename(file)) def quit_action_triggered(self): self.window.close() def pause_button_clicked(self): self.music_player.pause() def next_button_clicked(self): if self.music_player.currentMedia().isNull(): self.playlist.setCurrentIndex(1) self.music_player.play() else: self.playlist.next() #def play_all_button_clicked(self): # def play_button_clicked(self): if self.music_player.currentMedia().isNull(): self.playlist.setCurrentIndex(1) self.next_button_clicked() self.music_player.play() else: self.music_player.play() print(QMediaPlayer.EndOfMedia) def previous_button_clicked(self): self.playlist.previous() def progress_bar_maximum_changed(self, maximum): self.ProgressBar.setMaximum(maximum) # = self.music_player.duration() #def durationChanged(self, duration): # self.positionSlider.setRange(0, duration) def progress_bar_position_changed(self, position): self.ProgressBar.setValue(position) def repeat_once_button_clicked(self, status): self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemOnce) self.play_button_clicked() self.RepeatOnceRadioButton.setAutoExclusive(False) self.RepeatOnceRadioButton.setChecked(False) self.RepeatOnceRadioButton.setAutoExclusive(True) def repeat_button_clicked(self): self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemLoop) #def shuffle_checkbox_clicked(self): #add code #def shuttle_slider_moved(self): #add code def change_volume_level(self): self.music_player.setVolume(self.VolumeSlider.value())
class Channel(QObject): def __init__(self, name: T.Optional[str], parent: T.Optional[QObject] = None) -> None: super().__init__(parent) self.name = name self.slider_volume: Number = 100 self.threshold = PlaybackThreshold.Everything self._loop_sound: T.Optional[Sound] = None self._loop_player = QMediaPlayer(self) self._loop_volume_adjustment: Number = 0 self._loop_player.setAudioRole(QAudio.GameRole) self._loop_playlist = QMediaPlaylist(self) self._loop_playlist.setPlaybackMode(QMediaPlaylist.CurrentItemOnce) self._loop_player.setPlaylist(self._loop_playlist) self._loop_player.stateChanged.connect( self._on_loop_player_state_changed) self._one_shot_player = QMediaPlayer(self) self._one_shot_volume_adjustment: Number = 0 self._one_shot_player.setAudioRole(QAudio.GameRole) self._one_shot_player.stateChanged.connect( self._on_one_shot_player_state_changed) @property def is_playing(self): return (self._loop_player.state() == QMediaPlayer.PlayingState or self._one_shot_player.state() == QMediaPlayer.PlayingState) def _on_loop_player_state_changed(self, state: QMediaPlayer.State) -> None: logger.trace("Loop player state changed: {!r}", state) if state != QMediaPlayer.StoppedState: return decibel = -self._loop_volume_adjustment logger.trace("Readjusting loop player volume by {}db", decibel) self.adjust_player_volume_by_decibel(self._loop_player, decibel) self._loop_volume_adjustment = 0 # Loop playlist is empty if not self._loop_playlist.mediaCount(): logger.trace("Loop playlist is empty, not queueing a new file") return # This shouldn't ever happen, it's just here to make mypy happy if not self._loop_sound: return file = random.choices(self._loop_sound.files, [file.weight for file in self._loop_sound.files])[0] index = self._loop_sound.files.index(file) logger.trace( "Loop player playing file: {!r} at playlist index: {}", file, index, ) self._loop_playlist.setCurrentIndex(index) self._loop_player.play() def _on_one_shot_player_state_changed(self, state: QMediaPlayer.State) -> None: logger.trace("One-shot player state changed: {!r}", state) if state != QMediaPlayer.StoppedState: return decibel = -self._one_shot_volume_adjustment logger.trace("Readjusting one-shot player volume by {}db", decibel) self.adjust_player_volume_by_decibel(self._one_shot_player, decibel) self._one_shot_volume_adjustment = 0 logger.trace("One-shot player stopped, resuming loop player") self._loop_player.play() def play_sound(self, sound: Sound) -> None: if sound.playback_threshold > self.threshold: logger.trace("Ignoring sound {!r} because of threshold", sound) return if sound.loop is Loop.Start: self._loop_sound = sound # New looping sound, rebuild playlist self._loop_playlist.clear() for file in sound.files: media = QUrl.fromLocalFile(file.file_name) self._loop_playlist.addMedia(media) # Select file based on weight and set the matching playlist index weights = [file.weight for file in sound.files] file = random.choices(sound.files, weights)[0] index = sound.files.index(file) self._loop_playlist.setCurrentIndex(index) logger.trace("Adjusting loop player volume by {}db", file.volume_adjustment) self._loop_volume_adjustment = self.adjust_player_volume_by_decibel( self._loop_player, file.volume_adjustment) logger.trace("Adjusted One-shot player volume by {}db", self._loop_volume_adjustment) self._loop_player.play() logger.trace( "Loop player playing file: {!r} at playlist index: {}", file, index, ) return if sound.loop is Loop.Stop: logger.trace("Stopping loop player") self._loop_sound = None self._loop_playlist.clear() self._loop_player.stop() else: logger.trace("Pausing loop player for one-shot sound") self._loop_player.pause() file = random.choices(sound.files, [file.weight for file in sound.files])[0] media = QUrl.fromLocalFile(file.file_name) self._one_shot_player.setMedia(media) self._one_shot_volume_adjustment = self.adjust_player_volume_by_decibel( self._one_shot_player, file.volume_adjustment) logger.trace("Adjusted one-shot player volume by {}db", self._one_shot_volume_adjustment) self._one_shot_player.play() logger.trace("One-shot player playing file: {!r}", file) def set_player_volumes(self, volume: Number) -> None: volume = round(volume) self._loop_player.setVolume(volume) self._one_shot_player.setVolume(volume) # noinspection PyMethodMayBeStatic def adjust_player_volume_by_decibel(self, player: QMediaPlayer, decibel: Number) -> Number: original_volume = player.volume() target_volume = round( add_decibel_to_linear_volume(original_volume, decibel)) player.setVolume(target_volume) # Return clamped volume difference, so increasing linear volume 100 by n > 1 db # returns 0 return player.volume() - original_volume def set_threshold(self, threshold: PlaybackThreshold) -> None: logger.trace("Setting channel threshold: {!r}", threshold) self.threshold = threshold if not self._loop_sound: return if self._loop_sound.playback_threshold > threshold: logger.trace("Stopping loop player, new threshold too low") self._loop_playlist.clear() self._loop_player.stop() return logger.trace("Loop player state: {!r}", self._loop_player.state()) if (self._loop_sound.playback_threshold <= threshold and self._loop_player.state() == QMediaPlayer.StoppedState): logger.trace( "Replaying sound: {!r} in loop player from stopped state") self.play_sound(self._loop_sound)
class MainWindow(QObject): #class constructor def __init__(self, ui_file, parent=None): #reference to our music player self.music_player = QMediaPlayer() self.music_playlist = QMediaPlaylist() self.music_player.setVolume(80) #call parent QObject constructor super(MainWindow, self).__init__(parent) #load the UI file into Python ui_file = QFile(ui_file) ui_file.open(QFile.ReadOnly) loader = QUiLoader() self.window = loader.load(ui_file) self.window.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint) self.window.setWindowTitle("SynthWAV") #always remember to close files ui_file.close() #add event listeners open_action = self.window.findChild(QAction, 'action_open') open_action.triggered.connect(self.open_action_triggered) quit_action = self.window.findChild(QAction, 'action_quit') quit_action.triggered.connect(self.quit_action_triggered) open_button = self.window.findChild(QPushButton, 'open_button') open_button.clicked.connect(self.open_action_triggered) quit_button = self.window.findChild(QPushButton, 'quit_button') quit_button.clicked.connect(self.quit_action_triggered) play_button = self.window.findChild(QPushButton, 'play_button') play_button.clicked.connect(self.play_button_clicked) pause_button = self.window.findChild(QPushButton, 'pause_button') pause_button.clicked.connect(self.pause_button_clicked) stop_button = self.window.findChild(QPushButton, 'stop_button') stop_button.clicked.connect(self.stop_button_clicked) progress_slider = self.window.findChild(QSlider, 'progress_slider') self.music_player.positionChanged.connect(self.update_progress) progress_slider.sliderMoved.connect(self.scrub_progress) volume_slider = self.window.findChild(QSlider, 'volume_slider') volume_slider.setValue(self.music_player.volume()) volume_slider.sliderMoved.connect(self.adjust_volume) next_button = self.window.findChild(QPushButton, 'next_button') next_button.clicked.connect(self.next_button_clicked) previous_button = self.window.findChild(QPushButton, 'previous_button') previous_button.clicked.connect(self.previous_button_clicked) fforward_button = self.window.findChild(QPushButton, 'fforward_button') fforward_button.clicked.connect(self.fforward_button_clicked) fbackward_button = self.window.findChild(QPushButton, 'fbackward_button') fbackward_button.clicked.connect(self.fbackward_button_clicked) self.music_playlist.currentMediaChanged.connect(self.change_title) #show window to user self.window.show() def open_action_triggered(self): files = QFileDialog.getOpenFileNames(self.window, "Add songs to playlist") for i in range(len(files[0])): self.music_playlist.addMedia(QUrl.fromLocalFile(str(files[0][i]))) self.music_playlist.setCurrentIndex(0) self.music_player.setPlaylist(self.music_playlist) def change_title(self): title_label = self.window.findChild(QLabel, 'media_title') show_title_path = self.music_playlist.currentMedia().canonicalUrl( ).fileName() show_title = os.path.splitext(show_title_path) title_label.setText(show_title[0]) def quit_action_triggered(self): self.window.close() def play_button_clicked(self): self.music_player.play() def pause_button_clicked(self): self.music_player.pause() def stop_button_clicked(self): self.music_player.stop() def next_button_clicked(self): self.music_playlist.next() def previous_button_clicked(self): self.music_playlist.previous() def fforward_button_clicked(self): self.music_player.setPosition(self.music_player.position() + 10000) def fbackward_button_clicked(self): self.music_player.setPosition(self.music_player.position() - 10000) def update_progress(self): progress_slider = self.window.findChild(QSlider, 'progress_slider') if self.music_player.duration != 0: progress_slider.setMaximum(self.music_player.duration()) total_sec = (self.music_player.duration() / 1000) % 60 total_min = (self.music_player.duration() / (1000 * 60)) % 60 if (total_sec < 10): total_time = ("%d:0%d" % (int(total_min), int(total_sec))) else: total_time = ("%d:%d" % (int(total_min), int(total_sec))) track_duration_label = self.window.findChild( QLabel, 'track_duration_label') track_duration_label.setText(total_time) progress = self.music_player.position() progress_slider.setValue(progress) cur_sec = (self.music_player.position() / 1000) % 60 cur_min = (self.music_player.position() / (1000 * 60)) % 60 if (cur_sec < 10): cur_time = ("%d:0%d" % (int(cur_min), int(cur_sec))) else: cur_time = ("%d:%d" % (int(cur_min), int(cur_sec))) track_current_label = self.window.findChild(QLabel, 'track_current_label') track_current_label.setText(cur_time) def scrub_progress(self): progress_slider = self.window.findChild(QSlider, 'progress_slider') self.music_player.setPosition(progress_slider.sliderPosition()) cur_min = (self.music_player.position() / 1000) % 60 cur_sec = (self.music_player.position() / (1000 * 60)) % 60 if (cur_sec < 10): cur_time = ("%d:0%d" % (int(cur_min), int(cur_sec))) else: cur_time = ("%d:%d" % (int(cur_min), int(cur_sec))) track_current_label = self.window.findChild(QLabel, 'track_current_label') track_current_label.setText(cur_time) def adjust_volume(self): volume_slider = self.window.findChild(QSlider, 'volume_slider') self.music_player.setVolume(volume_slider.sliderPosition())
class MainWindow(QMainWindow): """Display video loop and controls""" audio_changed = Signal(str) def __init__(self, parent=None): super().__init__(parent) # Default values. Updated if found in config.JSON self.use_qt_thread = False self.rhythm_algorithm = "multifeature" self.default_device_name = "" self.show_video_preview = True self.video_loop_bpm = 60 self.video_update_skip_ms = 100 self.limit_tempo_by_default = False self.tempo_lower_limit = 60.0 self.tempo_upper_limit = 120.0 self.screen = 0 self.spotify_track_id = "" self.read_config() self.setWindowTitle("Gandalf Enjoys Music") self.desktop = QApplication.desktop() self.audio = AudioDevice(self.default_device_name) self.input_devices = self.audio.get_input_device_names() self.audio_changed.connect(self.audio.change_audio_input) if self.use_qt_thread: self.bpm_extractor = BPMQt(self.update_bpm, algorithm=self.rhythm_algorithm) else: self.bpm_extractor = BPMmp(self.update_bpm, algorithm=self.rhythm_algorithm) self.audio.data_ready.connect(self.bpm_extractor.start_bpm_calculation) self.init_ui() def init_ui(self): dir_path = os.path.dirname(os.path.realpath(__file__)) file_location = dir_path + "/resources/gandalf_icon_256px.png" self.icon_pixmap = QPixmap(file_location) self.icon = QIcon(self.icon_pixmap) self.setWindowIcon(self.icon) self.setWindowIconText("Gandalf Enjoys Music") self.central = QWidget(self) self.setCentralWidget(self.central) self.layout = QVBoxLayout() self.lock_checkbox = QCheckBox("Manual tempo", self) self.lock_checkbox.clicked.connect(self.update_lock_checkbox) self.limit_layout = QVBoxLayout() self.limit_checkbox = QCheckBox("Limit tempo between:", self) self.limit_checkbox.setChecked(self.limit_tempo_by_default) self.limit_checkbox.clicked.connect(self.update_bpm_manually) self.init_video() if self.show_video_preview: self.setFixedSize(QSize(500, 350)) self.layout.addWidget(self.video_widget) else: self.setFixedSize(500, 100) self.fullscreen_button = QPushButton(self) self.fullscreen_button.setText("Go Fullscreen") self.layout.addWidget(self.fullscreen_button) self.fullscreen_button.clicked.connect(self.show_fullscreen) self.video_widget.fullscreen_changed.connect( self.update_button_text) self.video_widget.fullscreen_changed.connect( self.reset_video_position ) self.tempo_control_layout = QVBoxLayout() self.tempo_control_layout.addWidget(self.lock_checkbox) self.set_bpm_widget = QLineEdit("{:.1f}".format(self.old_bpm), self) self.set_bpm_widget.setMaxLength(5) self.set_bpm_widget.returnPressed.connect(self.update_bpm_manually) self.set_bpm_palette = QPalette() self.set_bpm_palette.setColor(QPalette.Text, Qt.gray) self.set_bpm_widget.setPalette(self.set_bpm_palette) self.set_bpm_widget.setFixedWidth(50) self.tempo_control_layout.addWidget(self.set_bpm_widget) self.limit_layout.addWidget(self.limit_checkbox) self.limits = QHBoxLayout() self.lower_bpm_widget = QLineEdit(str(self.tempo_lower_limit), self) self.lower_bpm_widget.setMaxLength(5) self.lower_bpm_widget.returnPressed.connect(self.update_lower_limit) self.lower_bpm_widget.setFixedWidth(50) self.limits.addWidget(self.lower_bpm_widget) self.upper_bpm_widget = QLineEdit(str(self.tempo_upper_limit), self) self.upper_bpm_widget.setMaxLength(5) self.upper_bpm_widget.returnPressed.connect(self.update_upper_limit) self.upper_bpm_widget.setFixedWidth(50) self.limits.addWidget(self.upper_bpm_widget) self.limit_layout.addLayout(self.limits) self.control_layout = QHBoxLayout() self.control_layout.addLayout(self.tempo_control_layout) self.control_layout.addLayout(self.limit_layout) self.save_settings_button = QPushButton("Save settings", self) self.save_settings_button.clicked.connect(self.save_config) self.control_layout.addWidget(self.save_settings_button) self.layout.addLayout(self.control_layout) self.device_layout = QHBoxLayout() self.audio_select_label = QLabel("Audio device:", self) self.device_layout.addWidget(self.audio_select_label) self.audio_selection = QComboBox(self) self.audio_selection.addItems(self.input_devices) self.audio_selection.currentIndexChanged.connect(self.audio_selection_changed) self.device_layout.addWidget(self.audio_selection) self.layout.addLayout(self.device_layout) self.central.setLayout(self.layout) def init_video(self): self.old_bpm = 1.0 self.video_widget = VideoWidget(self, self.show_video_preview, self.screen) self.media_player = QMediaPlayer(self.central) self.media_player.setVideoOutput(self.video_widget) self.playlist = QMediaPlaylist(self.media_player) dir_path = os.path.dirname(os.path.realpath(__file__)) file_location = dir_path + "/resources/video_long.mp4" self.video_file = QUrl.fromLocalFile(file_location) self.playlist.addMedia(self.video_file) self.playlist.setPlaybackMode(QMediaPlaylist.Loop) self.playlist.setCurrentIndex(0) self.media_player.setPlaylist(self.playlist) self.media_player.mediaStatusChanged.connect(self.handle_media_state_changed) self.media_player.play() self.change_playback_rate(self.video_loop_bpm) if not self.show_video_preview: self.video_widget.hide() def handle_media_state_changed(self, state): if state == QMediaPlayer.MediaStatus.BufferedMedia: playback_speed = self.old_bpm / self.video_loop_bpm self.media_player.setPlaybackRate(playback_speed) self.media_player.setPosition(0) def change_playback_rate(self, bpm): """Update playback speed for video loop.""" if bpm != self.old_bpm: # Prevent switching between double and half tempo during the same song in spotify track_id = get_spotify_track() if not self.lock_checkbox.isChecked()\ and not self.limit_checkbox.isChecked()\ and (math.isclose(bpm*2,self.old_bpm, rel_tol=3e-2)\ or math.isclose(bpm, self.old_bpm*2, rel_tol=3e-2))\ and track_id and track_id == self.spotify_track_id: self.spotify_track_id = track_id return self.spotify_track_id = track_id self.old_bpm = bpm playback_speed = bpm / self.video_loop_bpm # Workaround for a bug which causes irregular video playback speed # after changing playback rate current_position = self.media_player.position() self.media_player.setPlaybackRate(playback_speed) self.media_player.setPosition(current_position + self.video_update_skip_ms * playback_speed) def update_bpm(self, bpm, manual=False): if not manual: if self.lock_checkbox.isChecked(): return bpm = float(int(bpm+0.5)) if self.limit_checkbox.isChecked(): while bpm < self.tempo_lower_limit: bpm = bpm * 2.0 while bpm > self.tempo_upper_limit: bpm = bpm / 2.0 self.change_playback_rate(bpm) self.set_bpm_widget.setText("{:.1f}".format(self.old_bpm)) def update_bpm_manually(self): bpm = self.set_bpm_widget.text() try: bpm = float(bpm) if bpm < 1.0: raise ValueError except ValueError: return self.spotify_track_id = "" self.update_bpm(bpm, manual=True) def update_lock_checkbox(self): if self.lock_checkbox.isChecked(): self.set_bpm_palette = QPalette() self.set_bpm_palette.setColor(QPalette.Text, Qt.black) self.set_bpm_widget.setPalette(self.set_bpm_palette) self.set_bpm_widget.setReadOnly(False) else: self.set_bpm_palette = QPalette() self.set_bpm_palette.setColor(QPalette.Text, Qt.gray) self.set_bpm_widget.setPalette(self.set_bpm_palette) self.set_bpm_widget.setReadOnly(True) def update_lower_limit(self, value=None): if not value: value = self.lower_bpm_widget.text() try: value = float(value) if value < 1.0: raise ValueError except ValueError: return if value <= self.tempo_upper_limit / 2.0: self.tempo_lower_limit = value else: self.tempo_lower_limit = self.tempo_upper_limit / 2.0 self.lower_bpm_widget.setText("{:.1f}".format(self.tempo_lower_limit)) def update_upper_limit(self, value=None): if not value: value = self.upper_bpm_widget.text() try: value = float(value) if value < 1.0: raise ValueError except ValueError: return if value >= self.tempo_lower_limit * 2.0: self.tempo_upper_limit = value else: self.tempo_upper_limit = self.tempo_lower_limit * 2.0 self.upper_bpm_widget.setText("{:.1f}".format(self.tempo_upper_limit)) def audio_selection_changed(self, idx): self.audio_changed.emit(self.audio_selection.currentText()) @Slot() def show_fullscreen(self): self.reset_video_position() if self.video_widget.isFullScreen(): self.video_widget.hide() self.fullscreen_button.setText("Go Fullscreen") else: self.video_widget.setFullScreen(True) self.video_widget.setGeometry(self.desktop.screenGeometry(self.screen)) self.fullscreen_button.setText("Hide Fullscreen") @Slot() def reset_video_position(self): self.media_player.setPosition(0) @Slot(bool) def update_button_text(self, fullscreen_status): if fullscreen_status: self.fullscreen_button.setText("Hide Fullscreen") else: self.fullscreen_button.setText("Go Fullscreen") def read_config(self): with open("config.JSON") as config_file: config = json.load(config_file) if "no_multiprocess" in config: self.use_qt_thread = config["no_multiprocess"] if config.get("rhythm_algorithm_faster"): self.rhythm_algorithm = "degara" if config.get("default_device"): self.default_device_name = config["default_device"] if "show_video_preview" in config: self.show_video_preview = config.get("show_video_preview") if config.get("video_loop_bpm"): self.video_loop_bpm = config["video_loop_bpm"] if config.get("video_update_skip_time_ms"): self.video_update_skip_ms = config["video_update_skip_time_ms"] if config.get("limit_tempo_by_default"): self.limit_tempo_by_default = config["limit_tempo_by_default"] if config.get("tempo_lower_limit"): self.tempo_lower_limit = config["tempo_lower_limit"] if config.get("tempo_upper_limit"): self.tempo_upper_limit = config["tempo_upper_limit"] if "screen" in config: self.screen = config["screen"] @Slot() def save_config(self): fast_rhythm_algo = self.rhythm_algorithm == "degara" data = { "no_multiprocess": self.use_qt_thread, "rhythm_algorithm_faster": fast_rhythm_algo, "default_device": self.audio_selection.currentText(), "show_video_preview": self.show_video_preview, "video_loop_bpm": self.video_loop_bpm, "video_update_skip_time_ms": self.video_update_skip_ms, "limit_tempo_by_default": self.limit_checkbox.isChecked(), "tempo_lower_limit": self.tempo_lower_limit, "tempo_upper_limit": self.tempo_upper_limit, "screen": self.screen } with open("config.JSON", "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=4)
class YoutubePlayer(QObject): titlesListChanged = Signal(list) def __init__(self, titles: List[Title] = [], widgetToPlay: QVideoWidget = None): QObject.__init__(self) self.__titles = titles self.__playlist = QMediaPlaylist(self) self.__player = QMediaPlayer(self) self.__videoWidget = widgetToPlay self.__player.setVideoOutput(self.__videoWidget) self.titlesListChanged.connect(self.resetPlayList) @property def titles(self): return self.__titles @titles.setter def titles(self, value): self.__titles = value self.titlesListChanged.emit(self.__titles) @Slot() def setTitles(self, titles: List[Title]): self.__titles = titles self.titlesListChanged.emit(self.__titles) @Slot() def resetPlayList(self, list_of_titles: List[Title]): self.__playlist.clear() for t in list_of_titles: url = t.link video = pafy.new(url) best = video.getbest() self.__playlist.addMedia(QMediaContent(QUrl(best.url))) self.__playlist.setCurrentIndex(0) self.__player.setPlaylist(self.__playlist) @Slot() def playVideo(self, index: int): self.__playlist.setCurrentIndex(index) self.__player.play() @Slot() def stopVideo(self): self.__player.stop() @Slot() def pauseVideo(self): if self.__player.state() == QMediaPlayer.PlayingState: self.__player.pause() else: self.__player.play()