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()
예제 #2
0
class ToneBoxApp(QApplication):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.settings_model = SettingsModel()
        self.manager_model = manager_model.Model(
            self.settings_model.get("DatabasePath"))
        self.queue_manager = queue_manager.QueueManager(self.manager_model)
        self.player_object = QMediaPlayer()
        self.player_object.setPlaylist(self.queue_manager)
        self.queue_manager.player_object = self.player_object
        self.main_window = MainWindow(self.settings_model, self.manager_model,
                                      self.queue_manager)
        self.queue_manager.player_widget = self.main_window.playerWidget
        self.main_window.playerWidget.queue_manager = self.queue_manager
        self.queue_manager.queue_widget = self.main_window.queueWidget
        self.main_window.queueWidget.queue_manager = self.queue_manager
        self.queue_manager.setup_signals()
        self.main_window.show()
예제 #3
0
class VideoMediaView_(MediaView):
    def __init__(self, media, parent):
        super(VideoMediaView_, self).__init__(media, parent)
        self.widget = QVideoWidget(parent)
        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()
        self.player.setPlaylist(self.playlist)
        self.player.setVideoOutput(self.widget)
        self.widget.setGeometry(media['geometry'])
        self.set_default_widget_prop()
        self.widget.setDisabled(True)

    @Slot()
    def play(self):
        self.finished = 0
        path = '%s/%s' % (self.save_dir, self.options['uri'])
        self.playlist.addMedia(QMediaContent(path))
        self.player.play()

        self.widget.show()
        self.widget.raise_()
        if float(self.duration) > 0:
            self.play_timer.setInterval(int(float(self.duration) * 1000))
            self.play_timer.start()
        self.started_signal.emit()

    @Slot()
    def stop(self, delete_widget=False):
        #---- kong ----
        if not self.widget:
            return False
        self.player.stop()
        self.playlist = None
        self.player = None
        super(VideoMediaView_, self).stop(delete_widget)
        return True
예제 #4
0
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)
        self.videoWidget = QVideoWidget()
        self.mediaPlayer = QMediaPlayer()
        self.mediaPlaylist = QMediaPlaylist()
        # Add the video file path
        self.mediaPlaylist.addMedia(QUrl.fromLocalFile(os.path.abspath("./sample_data/sampleVideo.mp4")))
        # Set the video to played in a loop once it ends.
        self.mediaPlaylist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop)
        # Set the QMediaPlaylist for the QMediaPlayer.
        self.mediaPlayer.setPlaylist(self.mediaPlaylist)
        # Add the QVideoWidget in the GridLayout.
        self.playerLayout.addWidget(self.videoWidget)
        # Set the video output from the QMediaPlayer to the QVideoWidget.
        self.mediaPlayer.setVideoOutput(self.videoWidget)
        # Set the QPushButtons to play, pause and stop the video in the QVideoWidget.
        self.playButton.clicked.connect(self.play_video)
        self.pauseButton.clicked.connect(self.pause_video)
        self.stopButton.clicked.connect(self.stop_video)
        # Set the total range for the QSlider.
        self.mediaPlayer.durationChanged.connect(self.change_duration)
        # Set the current value for the QSlider.
        self.mediaPlayer.positionChanged.connect(self.change_position)
        # Set the video position in QMediaPlayer based on the QSlider position.
        self.horizontalSlider.sliderMoved.connect(self.video_position)

    def play_video(self):
        """
        Handles the clicked signal generated by playButton and plays the video in the mediaPlayer.
        """
        self.mediaPlayer.play()

    def pause_video(self):
        """
        Handles the clicked signal generated by playButton and pauses video in the mediaPlayer.
        """
        self.mediaPlayer.pause()

    def stop_video(self):
        """
        Handles the clicked signal generated by playButton and stops the video in the mediaPlayer.
        """
        self.mediaPlayer.stop()

    def change_position(self, position):
        """
        Handles the positionChanged signal generated by the mediaPlayer.
        Sets the current value of the QSlider to the current position of the video in the QMediaPlayer.
        :param position: current position of the video in the QMediaPlayer.
        """
        self.horizontalSlider.setValue(position)

    def change_duration(self, duration):
        """
        Handles the durationChanged signal generated by the mediaPlayer.
        Sets the range of the QSlider.
        :param duration: Total duration of the video in the QMediaPlayer.
        """
        self.horizontalSlider.setRange(0, duration)

    def video_position(self, position):
        """
        Handles the sliderMoved signal generated by the horizontalSlider.
        Changes the position of the video in the QMediaPlayer on changing the value of the QSlider.
        :param position: Current position value of the QSlider.
        :return:
        """
        self.mediaPlayer.setPosition(position)
예제 #5
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.player = QMediaPlayer()
        self.playlist = QMediaPlaylist()

        toolBar = QToolBar()
        self.addToolBar(toolBar)
        playIcon = self.style().standardIcon(QStyle.SP_MediaPlay)
        previousIcon = self.style().standardIcon(QStyle.SP_MediaSkipBackward)
        nextIcon = self.style().standardIcon(QStyle.SP_MediaSkipForward)
        pauseIcon = self.style().standardIcon(QStyle.SP_MediaPause)
        stopIcon = self.style().standardIcon(QStyle.SP_MediaStop)

        self.playAction = toolBar.addAction(playIcon, "Play")
        self.previousAction = toolBar.addAction(previousIcon, "Previous")
        self.nextAction = toolBar.addAction(nextIcon, "Next")
        self.pauseAction = toolBar.addAction(pauseIcon, "Pause")
        self.stopAction = toolBar.addAction(stopIcon, "Stop")
        self.playAction.triggered.connect(self.player.play)
        self.previousAction.triggered.connect(self.previousClicked)
        self.nextAction.triggered.connect(self.playlist.next)
        self.pauseAction.triggered.connect(self.player.pause)
        self.stopAction.triggered.connect(self.player.stop)

        self.volSlider = QSlider()
        self.volSlider.setOrientation(Qt.Horizontal)
        self.volSlider.setMinimum(0)
        self.volSlider.setMaximum(100)
        self.volSlider.setFixedWidth(120)
        self.volSlider.setValue(self.player.volume())
        self.volSlider.setTickInterval(10)
        self.volSlider.setTickPosition(QSlider.TicksBelow)
        self.volSlider.setToolTip("Volume")
        self.volSlider.valueChanged.connect(self.player.setVolume)
        toolBar.addWidget(self.volSlider)

        openAction = QAction(QIcon.fromTheme("document-open"),
                             "&Open...",
                             self,
                             shortcut=QKeySequence.Open,
                             triggered=self.open)
        exitAction = QAction(QIcon.fromTheme("application-exit"),
                             "E&xit",
                             self,
                             shortcut="Ctrl+Q",
                             triggered=self.close)
        aboutQtAct = QAction("About &Qt", self, triggered=qApp.aboutQt)
        fileMenu = self.menuBar().addMenu("&File")
        fileMenu.addAction(openAction)
        fileMenu.addAction(exitAction)
        playMenu = self.menuBar().addMenu("&Play")
        playMenu.addAction(self.playAction)
        playMenu.addAction(self.previousAction)
        playMenu.addAction(self.nextAction)
        playMenu.addAction(self.pauseAction)
        playMenu.addAction(self.stopAction)
        aboutMenu = self.menuBar().addMenu("&About")
        aboutMenu.addAction(aboutQtAct)

        self.videoWidget = QVideoWidget()
        self.setCentralWidget(self.videoWidget)

        self.player.setPlaylist(self.playlist)
        self.player.stateChanged.connect(self.updateButtons)
        self.player.setVideoOutput(self.videoWidget)
        self.updateButtons(self.player.state())

    def open(self):
        fileDialog = QFileDialog(self)
        supportedMimeTypes = ["video/mp4", "*.*"]
        fileDialog.setMimeTypeFilters(supportedMimeTypes)
        moviesLocation = QStandardPaths.writableLocation(
            QStandardPaths.MoviesLocation)
        fileDialog.setDirectory(moviesLocation)
        if fileDialog.exec_() == QDialog.Accepted:
            self.playlist.addMedia(fileDialog.selectedUrls()[0])
            self.player.play()

    def previousClicked(self):
        if self.player.position() <= 5000:
            self.playlist.previous()
        else:
            player.setPosition(0)

    def updateButtons(self, state):
        mediaCount = self.playlist.mediaCount()
        self.playAction.setEnabled(mediaCount > 0
                                   and state != QMediaPlayer.PlayingState)
        self.pauseAction.setEnabled(state == QMediaPlayer.PlayingState)
        self.stopAction.setEnabled(state != QMediaPlayer.StoppedState)
        self.previousAction.setEnabled(self.player.position() > 0)
        self.nextAction.setEnabled(mediaCount > 1)
예제 #6
0
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)
예제 #7
0
class Board(QMainWindow, board_funcs):
    """
     Description
    -------------
        The board for Trivial Purfuit.
        TODO: JGC - Merge the common stuff between board_funcs and this class.
                    There's duplicate code, but you did everything in this class first.
    """
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Trivial Purfuit Board")
        self.num_row_tiles = 9
        self.num_col_tiles = 9

        self.board_tile_width = 95
        self.board_tile_height = self.board_tile_width

        self.board_width = self.num_row_tiles * self.board_tile_width
        self.board_height = self.num_col_tiles * self.board_tile_height

        monitor = QApplication.desktop().geometry()
        self.resize(monitor.width(), self.board_height)

        #default is event
        self.qtype1_tile_color = Qt.white
        #default is holidau
        self.qtype2_tile_color = Qt.green
        #default is location
        self.qtype3_tile_color = Qt.blue
        #default is people
        self.qtype4_tile_color = Qt.red
        self.roll_again_tile_color = Qt.darkGray

        self.players_initialized = False
        self.dice_initialized = False

        # Background music playlist
        self.playlist = QMediaPlaylist()

        self.playlist.addMedia(
            QUrl.fromLocalFile(
                definitions.ROOT_DIR +
                "/Trivial_Purfuit/resources/audio/sea_change.mp3"))
        self.playlist.addMedia(
            QUrl.fromLocalFile(definitions.ROOT_DIR +
                               "/Trivial_Purfuit/resources/audio/feblu.mp3"))
        self.playlist.addMedia(
            QUrl.fromLocalFile(
                definitions.ROOT_DIR +
                "/Trivial_Purfuit/resources/audio/vals_de_rodrigues.mp3"))
        self.playlist.addMedia(
            QUrl.fromLocalFile(
                definitions.ROOT_DIR +
                "/Trivial_Purfuit/resources/audio/escaping_time.mp3"))

        self.playlist.setPlaybackMode(QMediaPlaylist.Loop)

        self.playlist_player = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.playlist_player.setPlaylist(self.playlist)

        self.number_of_players = 0
        self.player_list = []
        self.die = Die()
        self.board_menu = BoardMenu()
        self.qa_manager = QuestionManager(
            definitions.ROOT_DIR +
            "/Trivial_Purfuit/csvs/questions-and-answers.csv")
        self.question_categories = [
            definitions.question_type1, definitions.question_type2,
            definitions.question_type3, definitions.question_type4
        ]
        self.image_path = definitions.ROOT_DIR + "/Trivial_Purfuit/src/board/images/"
        self.restart_menu = RestartMenu()

    # end __init__()

    def initialize_game(self):
        """
         Description
        -------------
         - TODO: JGC
        """
        monitor = QApplication.desktop().geometry()

        # Navigation Menu setup
        self.board_menu.resize(monitor.width(), monitor.height())
        self.board_menu.ui.player_order_group_box.move(
            self.board_width, self.board_menu.ui.player_order_group_box.y())
        self.board_menu.ui.navigation_group.move(self.board_width,
                                                 monitor.height() / 3)

        temp_x = self.board_menu.ui.navigation_group.x()
        temp_y = self.board_menu.ui.navigation_group.y(
        ) + self.board_menu.ui.navigation_group.height()

        self.board_menu.ui.misc_group.move(temp_x, temp_y)
        self.board_menu.ui.audio_group.move(
            self.board_menu.ui.misc_group.x(),
            self.board_menu.ui.misc_group.y() +
            self.board_menu.ui.misc_group.height())
        # Connect signals/slots for buttons on board menu
        self.connect(self.board_menu.ui.up_button, SIGNAL("clicked()"),
                     partial(self.start_move, "UP"))
        self.connect(self.board_menu.ui.down_button, SIGNAL("clicked()"),
                     partial(self.start_move, "DOWN"))
        self.connect(self.board_menu.ui.left_button, SIGNAL("clicked()"),
                     partial(self.start_move, "LEFT"))
        self.connect(self.board_menu.ui.right_button, SIGNAL("clicked()"),
                     partial(self.start_move, "RIGHT"))
        self.connect(self.board_menu.ui.reset_button, SIGNAL("clicked()"),
                     self.cheat)
        self.connect(self.board_menu.ui.roll_die_button, SIGNAL("clicked()"),
                     self.get_dice_value)

        # Connect signals/slots for audio slider widgets on board menu
        self.connect(self.board_menu.ui.music_volume_slider,
                     SIGNAL("sliderReleased()"), self.update_music_volume)
        self.connect(self.board_menu.ui.sound_effects_volume,
                     SIGNAL("sliderReleased()"),
                     self.update_sound_effect_volume)
        self.board_menu.ui.sound_effects_volume.setValue(50)
        self.board_menu.ui.music_volume_slider.setValue(50)

        # Die Setup/initialization
        self.initialize_dice()

        # Game sounds
        self.win_noise = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.lose_noise = QMediaPlayer(None, QMediaPlayer.VideoSurface)
        self.win_noise.setMedia(
            QUrl.fromLocalFile(
                definitions.ROOT_DIR +
                "/Trivial_Purfuit/resources/audio/win_bing.mp3"))
        self.lose_noise.setMedia(
            QUrl.fromLocalFile(
                definitions.ROOT_DIR +
                "/Trivial_Purfuit/resources/audio/lose_noise.mp3"))

        # Start the background music
        self.playlist_player.play()

        self.layout().addChildWidget(self.die)
        self.layout().addChildWidget(self.board_menu)

        self.player_list = self.set_round_order(self.player_list)
        self.current_player = self.player_list[0]
        self.current_player_list_index = 0
        self.current_player.is_current_player = True
        self.board_menu.ui.current_player_field.insertPlainText(
            str(self.current_player.name))

    # end initialize_game()

    def hide_dirs(self):
        self.board_menu.ui.down_button.setVisible(False)
        self.board_menu.ui.up_button.setVisible(False)
        self.board_menu.ui.left_button.setVisible(False)
        self.board_menu.ui.right_button.setVisible(False)

    #end hide_dirs

    def avail_dirs(self):
        """
        Determines possible directions the player could move based on current location
        Input: The player token who is currently moving
        Output: List of available directions
        """
        player_row = self.current_player.location[0]
        player_col = self.current_player.location[1]
        directions = list()

        if self.get_tile_type(player_row + 1, player_col) != "Invalid":
            directions.append("Down")
        if self.get_tile_type(player_row - 1, player_col) != "Invalid":
            directions.append("Up")
        if self.get_tile_type(player_row, player_col - 1) != "Invalid":
            directions.append("Left")
        if self.get_tile_type(player_row, player_col + 1) != "Invalid":
            directions.append("Right")

        return directions

    def update_dirs(self):
        """
        Hides the movement buttons based on whether or not its a valid move
        Input:
        Output:
        """
        player_row = self.current_player.location[0]
        player_col = self.current_player.location[1]
        self.board_menu.ui.down_button.setVisible(True)
        self.board_menu.ui.up_button.setVisible(True)
        self.board_menu.ui.left_button.setVisible(True)
        self.board_menu.ui.right_button.setVisible(True)

        if self.get_tile_type(player_row + 1, player_col) == "Invalid" \
                or self.current_player.direction_to_move == "UP":
            self.board_menu.ui.down_button.setVisible(False)
        if self.get_tile_type(player_row - 1, player_col) == "Invalid" \
                or self.current_player.direction_to_move == "DOWN":
            self.board_menu.ui.up_button.setVisible(False)
        if self.get_tile_type(player_row, player_col - 1) == "Invalid" \
                or self.current_player.direction_to_move == "RIGHT":
            self.board_menu.ui.left_button.setVisible(False)
        if self.get_tile_type(player_row, player_col + 1) == "Invalid" \
                or self.current_player.direction_to_move == "LEFT":
            self.board_menu.ui.right_button.setVisible(False)

    # end update_dirs()

    def set_default_game_volume(self):
        self.playlist_player.setVolume(50)
        self.board_menu.ui.music_volume_slider.setValue(50)
        self.board_menu.ui.music_volume_slider.setValue(50)

    # end set_default_game_volume

    def update_music_volume(self):
        tmp_volume = self.board_menu.ui.music_volume_slider.value()
        self.playlist_player.setVolume(tmp_volume)

    # end update_music_volume()

    def update_sound_effect_volume(self):
        tmp_volume = self.board_menu.ui.sound_effects_volume.value()

        # Set volume for lose/win effects
        self.win_noise.setVolume(tmp_volume)
        self.lose_noise.setVolume(tmp_volume)

        # Set the volume for each player token
        for player in self.player_list:
            player.audio_player.setVolume(tmp_volume)

        # Set the die volume
        self.die.audio_player.setVolume(tmp_volume)

    # end update_sound_effect_volume()

    def get_dice_value(self):
        """
         Description
        -------------
         - TODO: JGC
        """
        self.current_player.moves_left = self.die.roll()
        self.current_player.direction_to_move = "NONE"
        self.board_menu.ui.dice_field.clear()
        self.board_menu.ui.dice_field.insertPlainText(
            str(self.current_player.moves_left))
        self.board_menu.ui.current_player_field.clear()
        self.board_menu.ui.current_player_field.insertPlainText(
            str(self.current_player.name))

        self.update_dirs()
        self.board_menu.ui.roll_die_button.setVisible(False)

        if self.current_player.moves_left == 6:
            self.current_player.moves_left = 0
            self.hide_dirs()
            self.board_menu.ui.roll_die_button.setVisible(True)
            answer, valid_input = QInputDialog().getItem(
                self, "Select Cake Headquarters", "Select:",
                self.question_categories, 0, False)

            if answer == self.question_categories[0]:
                self.current_player.location[0] = 4
                self.current_player.location[1] = 8
                self.current_player.x = self.board_tile_width * 9 - (
                    self.current_player.width * self.current_player.x_offset)
                self.current_player.y = self.board_tile_height * 5 - (
                    self.current_player.height * self.current_player.y_offset)

            elif answer == self.question_categories[1]:
                self.current_player.location[0] = 8
                self.current_player.location[1] = 4
                self.current_player.x = self.board_tile_width * 5 - (
                    self.current_player.width * self.current_player.x_offset)
                self.current_player.y = self.board_tile_height * 9 - (
                    self.current_player.height * self.current_player.y_offset)

            elif answer == self.question_categories[2]:
                self.current_player.location[0] = 0
                self.current_player.location[1] = 4
                self.current_player.x = self.board_tile_width * 5 - (
                    self.current_player.width * self.current_player.x_offset)
                self.current_player.y = self.board_tile_height * 1 - (
                    self.current_player.height * self.current_player.y_offset)

            elif answer == self.question_categories[3]:
                self.current_player.location[0] = 4
                self.current_player.location[1] = 0
                self.current_player.x = self.board_tile_width * 1 - (
                    self.current_player.width * self.current_player.x_offset)
                self.current_player.y = self.board_tile_height * 5 - (
                    self.current_player.height * self.current_player.y_offset)

            else:
                print("Incorrect answer")

            self.current_player.turn_status = True
            self.current_player.draw_token = True
            self.current_player.update()
            self.perform_tile_action()
            self.board_menu.ui.dice_field.clear()

        # Updates the dice image to immediately reflect the correct image.
        self.die.update()

    # end get_dice_value()

    def start_move(self, label):
        """
         Description
        -------------
         - TODO: JGC
        """
        try:
            # TODO: Could add a check to restart for those too impatient.
            self.current_player.audio_player.play()

            if (label == "UP" or label == "DOWN" or label == "LEFT"
                    or label == "RIGHT"):

                while (self.current_player.moves_left > 0):
                    self.current_player.direction_to_move = label
                    self.current_player.turn_status = True

                    self.current_player.update_location(direction=label)
                    self.update_dirs()
                    self.current_player.moves_left = self.current_player.moves_left - 1
                    self.board_menu.ui.dice_field.clear()
                    self.board_menu.ui.dice_field.insertPlainText(
                        str(self.current_player.moves_left))

                    if len(self.avail_dirs()
                           ) > 2 and self.current_player.moves_left != 0:
                        break
                    else:
                        if self.current_player.location == [0, 0]:
                            if self.current_player.direction_to_move == "UP":
                                label = "RIGHT"
                            else:
                                label = "DOWN"
                        elif self.current_player.location == [0, 8]:
                            if self.current_player.direction_to_move == "UP":
                                label = "LEFT"
                            else:
                                label = "DOWN"
                        elif self.current_player.location == [8, 0]:
                            if self.current_player.direction_to_move == "DOWN":
                                label = "RIGHT"
                            else:
                                label = "UP"
                        elif self.current_player.location == [8, 8]:
                            if self.current_player.direction_to_move == "DOWN":
                                label = "LEFT"
                            else:
                                label = "UP"

                    if self.current_player.moves_left == 0:
                        self.current_player.done_moving = True
                    # end if

                    # Manually calls the paint QEvent.
                    self.update()

                    # Once the player is out of spaces to move, prompt the player with a
                    # question from the QA Manager.
                    if self.current_player.moves_left == 0 and self.current_player.done_moving:
                        self.current_player.direction_to_move = "NONE"
                        self.hide_dirs()
                        self.board_menu.ui.roll_die_button.setVisible(True)
                        self.current_player.done_moving = False
                        self.perform_tile_action()
                    # end if

                else:
                    print("No moves left!")

        except ValueError:
            print("[ERROR] Invalid dice roll amount!")

    # end start_move()

    def initialize_player_tokens(self, total_players, player_one, player_two,
                                 player_three, player_four):
        """
         Description
        -------------
         TODO: JGC -

        """

        if total_players >= 1:
            self.player_widget = PlayerToken(player_one, self.board_tile_width,
                                             self.board_tile_height, 2.6, 2.6)
            self.player_widget.resize(self.board_width, self.board_height)
            self.layout().addChildWidget(self.player_widget)
            self.player_list.append(self.player_widget)

        if total_players >= 2:
            player_widget_two = PlayerToken(player_two, self.board_tile_width,
                                            self.board_tile_height, 1, 1)
            player_widget_two.resize(self.board_width, self.board_height)
            self.layout().addChildWidget(player_widget_two)
            self.player_list.append(player_widget_two)

        if total_players >= 3:
            player_widget_three = PlayerToken(player_three,
                                              self.board_tile_width,
                                              self.board_tile_height, 2.6, 1)
            player_widget_three.resize(self.board_width, self.board_height)
            self.layout().addChildWidget(player_widget_three)
            self.player_list.append(player_widget_three)

        if total_players >= 4:
            player_widget_four = PlayerToken(player_four,
                                             self.board_tile_width,
                                             self.board_tile_height, 1, 2.6)
            player_widget_four.resize(self.board_width, self.board_height)
            self.layout().addChildWidget(player_widget_four)
            self.player_list.append(player_widget_four)

    # end initialize_player_tokens()

    def initialize_dice(self):
        """
         Description
        -------------
         - TODO: JGC
        """
        self.die.board_tile_height = self.board_tile_height
        self.die.board_tile_width = self.board_tile_width
        self.die.resize(self.board_width, self.board_height)

    # end initialize_dice()

    def cheat(self):
        """
         Description
        -------------
         - TODO: JGC
        """
        self.current_player.award_cake_piece(self.question_categories[0])
        self.current_player.award_cake_piece(self.question_categories[1])
        self.current_player.award_cake_piece(self.question_categories[2])
        self.current_player.award_cake_piece(self.question_categories[3])
        self.current_player.update()

    # end reset_player()

    def is_roll_again_tile(self, row, col):
        """
         Description
        -------------
         Checks if the current row and column position is a holiday tile.

         Parameters
        -------------
         (1) row: The selected row on the board.
         (2) col: The selected column on the board.
        """
        if ((row == 0 and col == 0) or (row == 0 and col == 8)
                or (row == 8 and col == 0) or (row == 8 and col == 8)):
            return True
        # end if

    # end is_roll_again_tile()

    def is_qtype1_tile(self, row, col):
        """
         Description
        -------------
         Checks if the current row and column position is a person tile.

         Parameters
        -------------
         (1) row: The selected row on the board.
         (2) col: The selected column on the board.
        """
        if ((row == 0 and col == 3) or (row == 0 and col == 6)
                or (row == 1 and col == 0) or (row == 3 and col == 4)
                or (row == 4 and col == 2) or (row == 4 and col == 8)
                or (row == 5 and col == 0) or (row == 7 and col == 4)
                or (row == 8 and col == 1) or (row == 8 and col == 7)):
            return True
        # end if

    # end is_person_tile()

    def is_qtype2_tile(self, row, col):
        """
         Description
        -------------
         Checks if the current row and column position is an event tile.

         Parameters
        -------------
         (1) row: The selected row on the board.
         (2) col: The selected column on the board.
        """
        if ((row == 0 and col == 2) or (row == 0 and col == 5)
                or (row == 2 and col == 0) or (row == 2 and col == 4)
                or (row == 3 and col == 8) or (row == 4 and col == 1)
                or (row == 4 and col == 5) or (row == 7 and col == 0)
                or (row == 7 and col == 8) or (row == 8 and col == 4)):
            return True
        # end if

    # end is_event_tile()

    def is_qtype3_tile(self, row, col):
        """
         Description
        -------------
         Checks if the current row and column position is a location/place tile.

         Parameters
        -------------
         (1) row: The selected row on the board.
         (2) col: The selected column on the board.
        """
        if ((row == 0 and col == 4) or (row == 1 and col == 8)
                or (row == 3 and col == 0) or (row == 4 and col == 3)
                or (row == 4 and col == 7) or (row == 6 and col == 0)
                or (row == 6 and col == 4) or (row == 6 and col == 8)
                or (row == 8 and col == 2) or (row == 8 and col == 5)):
            return True
        # end if

    # end is_place_tile()

    def is_qtype4_tile(self, row, col):
        """
         Description
        -------------
         Checks if the current row and column position is a holiday tile.

         Parameters
        -------------
         (1) row: The selected row on the board.
         (2) col: The selected column on the board.
        """
        if ((row == 0 and col == 1) or (row == 0 and col == 7)
                or (row == 1 and col == 4) or (row == 2 and col == 8)
                or (row == 4 and col == 0) or (row == 4 and col == 6)
                or (row == 5 and col == 4) or (row == 5 and col == 8)
                or (row == 8 and col == 3) or (row == 8 and col == 6)):
            return True
        # end if

    # end is_holiday_tile()

    def is_hub_tile(self, row, col):
        """
        Description
        -------------
        Checks if the current row and column position is the hub tile.

        Parameters
        -------------
        (1) row: The selected row on the board.
        (2) col: The selected column on the board.
        """
        if (row == 4 and col == 4):
            return True

    # end is_hub_tile()

    def is_cake_tile(self, row, col):
        """
        Description
        -------------
        Checks if the current row and column position is a cake tile.

        Parameters
        -------------
        (1) row: The selected row on the board.
        (2) col: The selected column on the board.
        """
        if ((row == 0 and col == 4) or (row == 4 and col == 0)
                or (row == 4 and col == 8) or (row == 8 and col == 4)):
            return True

    # end is_cake_tile()

    def get_tile_type(self, row, col):
        """
        Description
        -------------
        Utilizes previous methods for tile checking to return a string of
        what tile type the current row and column position is

        Parameters
        -------------
        (1) row: The selected row on the board.
        (2) col: The selected column on the board.
        """
        if self.is_hub_tile(row, col):
            return "hub"
        elif self.is_qtype1_tile(row, col):
            return self.question_categories[0]
        elif self.is_qtype2_tile(row, col):
            return self.question_categories[1]
        elif self.is_qtype3_tile(row, col):
            return self.question_categories[2]
        elif self.is_qtype4_tile(row, col):
            return self.question_categories[3]
        elif self.is_roll_again_tile(row, col):
            return "roll_again"
        else:
            return "Invalid"

    # end get_tile_type()

    def paintEvent(self, event):
        """
         Description
        -------------
         - Draws the board and player tokens

         Parameters
        -------------
         (1) event: The event signal (QEvent.Type.Paint).
        """

        self.draw_board()

        if not self.dice_initialized:
            self.die.update()
            self.dice_initialized = True
        # end if

        for player in self.player_list:
            self.do_player_turn(player)

    # end paintEvent()

    def do_player_turn(self, player):
        """
         Description
        -------------
         TODO: JGC
        """

        if player.turn_status:
            player.draw_token = True
            player.update()
            player.turn_status = False
        # end if

    # end do_player_turn()

    def perform_tile_action(self):
        """
         Description
        -------------
         - TODO: JGC
        """
        self.current_player.update()
        tile_type = self.get_tile_type(self.current_player.location[0],
                                       self.current_player.location[1])

        roll_again = False

        if tile_type in self.question_categories:

            good_answer = self.ask_question(self.current_player,
                                            tile_type,
                                            isCake=False)

            if good_answer:
                self.win_noise.play()
                roll_again = True
                # Verify this is a "Cake" Tile before awarding cake piece.
                if self.is_cake_tile(self.current_player.location[0],
                                     self.current_player.location[1]):
                    self.current_player.award_cake_piece(
                        cake_category=tile_type)
            else:
                self.lose_noise.play()

        elif (tile_type == "roll_again"):
            self.win_noise.play()
            roll_again = True
            QMessageBox.question(self, 'Congratulations!', 'Roll Again!',
                                 QMessageBox.Ok)

        elif (tile_type == "hub"):
            # Verify the player token has all cake pieces awarded before answering the
            # winning question, otherwise ask random question
            if self.current_player.all_cake_pieces_present():
                answer, valid_input = QInputDialog().getItem(
                    self, "Select Category",
                    "!OTHER PLAYERS! Select the winning question category:",
                    self.question_categories, 0, False)
                good_answer = self.ask_question(self.current_player,
                                                answer,
                                                isCake=False)

                if good_answer:
                    self.win_noise.play()
                    QMessageBox.question(self, 'Congratulations!', 'YOU WIN!',
                                         QMessageBox.Ok)
                    self.restart_menu.show()
                else:
                    self.lose_noise.play()
            else:
                answer, valid_input = QInputDialog().getItem(
                    self, "Select Category", "Select the question category:",
                    self.question_categories, 0, False)
                good_answer = self.ask_question(self.current_player,
                                                answer,
                                                isCake=False)
                if good_answer:
                    roll_again = True
                else:
                    self.lose_noise.play()

        else:
            print("Invalid Tile/Question Type Received")
            print("Row: " + str(self.current_player.location[0]))
            print("Col: " + str(self.current_player.location[1]))

        # If not roll again tile, point to the next player in the list
        if not roll_again:
            # Deactivate the yellow outline for current player
            self.current_player.is_current_player = False
            self.current_player_list_index = (self.current_player_list_index +
                                              1) % len(self.player_list)
            self.current_player = self.player_list[
                self.current_player_list_index]
            self.current_player.is_current_player = True
            self.board_menu.ui.current_player_field.clear()
            self.board_menu.ui.current_player_field.insertPlainText(
                str(self.current_player.name))
            self.board_menu.ui.dice_field.clear()
        # end if

    # end perform_tile_action

    def draw_board(self):
        """
         Description
        -------------
         - Paint all of the tiles for the Trivial Purfuit board

         Parameters
        -------------
         (1) event: The event signal (QEvent.Type.Paint).

         NOTE/TODO
        -------------
         (1) Don't be lazy and brute force..
         (2) Run the current board layout by the team
        """
        painter = QPainter(self)
        painter.setPen(QPen(Qt.black, 5, Qt.SolidLine))

        x = 0
        y = 0

        # The board is drawn from left to right.
        for row in range(self.num_row_tiles):
            for col in range(self.num_col_tiles):

                if self.is_roll_again_tile(row, col):
                    painter.setBrush(
                        QBrush(self.roll_again_tile_color, Qt.SolidPattern))
                    painter.drawRect(x, y, self.board_tile_width,
                                     self.board_tile_height)
                    painter.drawImage(
                        QRect(x, y, self.board_tile_width,
                              self.board_tile_height),
                        QImage(self.image_path + "roll_again.png"))

                elif self.is_qtype1_tile(row, col):
                    painter.setBrush(
                        QBrush(self.qtype1_tile_color, Qt.SolidPattern))
                    painter.drawRect(x, y, self.board_tile_width,
                                     self.board_tile_height)
                    if self.is_cake_tile(row, col):
                        painter.drawImage(
                            QRect(x, y, self.board_tile_width,
                                  self.board_tile_height),
                            QImage(self.image_path + "collect.png"))

                elif self.is_qtype4_tile(row, col):
                    painter.setBrush(
                        QBrush(self.qtype4_tile_color, Qt.SolidPattern))
                    painter.drawRect(x, y, self.board_tile_width,
                                     self.board_tile_height)
                    if self.is_cake_tile(row, col):
                        painter.drawImage(
                            QRect(x, y, self.board_tile_width,
                                  self.board_tile_height),
                            QImage(self.image_path + "collect.png"))

                elif self.is_qtype2_tile(row, col):
                    painter.setBrush(
                        QBrush(self.qtype2_tile_color, Qt.SolidPattern))
                    painter.drawRect(x, y, self.board_tile_width,
                                     self.board_tile_height)
                    if self.is_cake_tile(row, col):
                        painter.drawImage(
                            QRect(x, y, self.board_tile_width,
                                  self.board_tile_height),
                            QImage(self.image_path + "collect.png"))

                elif self.is_qtype3_tile(row, col):
                    painter.setBrush(
                        QBrush(self.qtype3_tile_color, Qt.SolidPattern))
                    painter.drawRect(x, y, self.board_tile_width,
                                     self.board_tile_height)
                    if self.is_cake_tile(row, col):
                        painter.drawImage(
                            QRect(x, y, self.board_tile_width,
                                  self.board_tile_height),
                            QImage(self.image_path + "collect.png"))

                elif self.is_hub_tile(row, col):
                    painter.drawImage(
                        QRect(x, y, self.board_tile_width,
                              self.board_tile_height),
                        QImage(self.image_path + "win.png"))

                # Quadrant One
                elif row == 1 and col == 1:
                    painter.drawImage(
                        QRect(self.board_tile_width, self.board_tile_height,
                              self.board_tile_width * 3,
                              self.board_tile_height * 3),
                        QImage(self.image_path + "american_flag.jpeg"))

                # Quadrant Two
                elif row == 5 and col == 1:
                    painter.drawImage(
                        QRect(self.board_tile_width * row,
                              self.board_tile_height,
                              self.board_tile_width * 3,
                              self.board_tile_height * 3),
                        QImage(self.image_path + "fireworks-two.jpg"))

                # Quadrant Three
                elif row == 1 and col == 5:
                    painter.drawImage(
                        QRect(self.board_tile_width,
                              self.board_tile_height * col,
                              self.board_tile_width * 3,
                              self.board_tile_height * 3),
                        QImage(self.image_path + "underwear_guy.jpeg"))

                # Quadrant Four
                elif row == 5 and col == 5:
                    painter.drawImage(
                        QRect(self.board_tile_width * row,
                              self.board_tile_height * col,
                              self.board_tile_width * 3,
                              self.board_tile_height * 3),
                        QImage(self.image_path + "doi.jpg"))
                # end if

                # Update to x-coordinate for next tile
                x = x + self.board_tile_width
            # end for

            # Reset (x,y) starting coordinates for next row and columns
            y = y + self.board_tile_height
            x = 0
        # end for

        self.board_initialized = True
예제 #8
0
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())
예제 #9
0
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)
예제 #10
0
class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()

        self.playlist = QMediaPlaylist()
        self.player = QMediaPlayer()

        toolBar = QToolBar()
        self.addToolBar(toolBar)

        fileMenu = self.menuBar().addMenu("&File")
        openAction = QAction(QIcon.fromTheme("document-open"),
                             "&Open...", self, shortcut=QKeySequence.Open,
                             triggered=self.open)
        fileMenu.addAction(openAction)
        exitAction = QAction(QIcon.fromTheme("application-exit"), "E&xit",
                             self, shortcut="Ctrl+Q", triggered=self.close)
        fileMenu.addAction(exitAction)

        playMenu = self.menuBar().addMenu("&Play")
        playIcon = self.style().standardIcon(QStyle.SP_MediaPlay)
        self.playAction = toolBar.addAction(playIcon, "Play")
        self.playAction.triggered.connect(self.player.play)
        playMenu.addAction(self.playAction)

        previousIcon = self.style().standardIcon(QStyle.SP_MediaSkipBackward)
        self.previousAction = toolBar.addAction(previousIcon, "Previous")
        self.previousAction.triggered.connect(self.previousClicked)
        playMenu.addAction(self.previousAction)

        pauseIcon = self.style().standardIcon(QStyle.SP_MediaPause)
        self.pauseAction = toolBar.addAction(pauseIcon, "Pause")
        self.pauseAction.triggered.connect(self.player.pause)
        playMenu.addAction(self.pauseAction)

        nextIcon = self.style().standardIcon(QStyle.SP_MediaSkipForward)
        self.nextAction = toolBar.addAction(nextIcon, "Next")
        self.nextAction.triggered.connect(self.playlist.next)
        playMenu.addAction(self.nextAction)

        stopIcon = self.style().standardIcon(QStyle.SP_MediaStop)
        self.stopAction = toolBar.addAction(stopIcon, "Stop")
        self.stopAction.triggered.connect(self.player.stop)
        playMenu.addAction(self.stopAction)

        self.volumeSlider = QSlider()
        self.volumeSlider.setOrientation(Qt.Horizontal)
        self.volumeSlider.setMinimum(0)
        self.volumeSlider.setMaximum(100)
        self.volumeSlider.setFixedWidth(app.desktop().availableGeometry(self).width() / 10)
        self.volumeSlider.setValue(self.player.volume())
        self.volumeSlider.setTickInterval(10)
        self.volumeSlider.setTickPosition(QSlider.TicksBelow)
        self.volumeSlider.setToolTip("Volume")
        self.volumeSlider.valueChanged.connect(self.player.setVolume)
        toolBar.addWidget(self.volumeSlider)

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

        self.videoWidget = QVideoWidget()
        self.setCentralWidget(self.videoWidget)
        self.player.setPlaylist(self.playlist)
        self.player.stateChanged.connect(self.updateButtons)
        self.player.setVideoOutput(self.videoWidget)

        self.updateButtons(self.player.state())

    def open(self):
        fileDialog = QFileDialog(self)
        supportedMimeTypes = QMediaPlayer.supportedMimeTypes()
        if not supportedMimeTypes:
            supportedMimeTypes.append("video/x-msvideo") # AVI
        fileDialog.setMimeTypeFilters(supportedMimeTypes)
        moviesLocation = QStandardPaths.writableLocation(QStandardPaths.MoviesLocation)
        fileDialog.setDirectory(moviesLocation)
        if fileDialog.exec_() == QDialog.Accepted:
            self.playlist.addMedia(fileDialog.selectedUrls()[0])
            self.player.play()

    def previousClicked(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:
            self.playlist.previous()
        else:
            player.setPosition(0)

    def updateButtons(self, state):
        mediaCount = self.playlist.mediaCount()
        self.playAction.setEnabled(mediaCount > 0
            and state != QMediaPlayer.PlayingState)
        self.pauseAction.setEnabled(state == QMediaPlayer.PlayingState)
        self.stopAction.setEnabled(state != QMediaPlayer.StoppedState)
        self.previousAction.setEnabled(self.player.position() > 0)
        self.nextAction.setEnabled(mediaCount > 1)
예제 #11
0
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())
예제 #12
0
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)
예제 #13
0
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()