Как починить изменение текста на кнопках аудиоплеера?

Проблема заключается в методе play класса MyWindow. Моему коду приходится работать сразу с несколькими аудиофайлами, поэтому необходима возможность переключится с воспроизведения одной композиции на другую.

Раньше для каждого аудиофайла я создавал две кнопки - для старта и паузы. Но сейчас я объединил их в одну. Это вызвало проблему.

Если поставить на паузу один файл, а потом запустить воспроизведение второго, надпись 'Pause' остается на кнопке предыдущего файла:

введите сюда описание изображения

Достаточно базовая вещь, но я не могу придумать, как избежать ошибки. Пожалуйста, помогите починить код:

from PyQt5 import QtCore, QtWidgets, QtGui, QtMultimedia

class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.dict = {
            '1.Papercut.mp3': [],
            '13.Numb.mp3': []
        }
        self.song = ''

        self.player = QtMultimedia.QMediaPlayer()
        self.player.stateChanged.connect(self.player_state)

        self.qsl = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.qsl.sliderMoved[int].connect(self.set_play_position)
        self.qsl.sliderReleased.connect(self.slider_released)
        self.qsl.setEnabled(False)

        self.box = QtWidgets.QGridLayout(self)

        for line, song in enumerate(self.dict):           
            play_btn = QtWidgets.QPushButton('Play', clicked = lambda ch, song = song: self.play(song))

            label = QtWidgets.QLabel(song)
            self.box.addWidget(play_btn, line, 0)
            self.box.addWidget(label, line, 2)

            self.dict[song].append(play_btn)

        self.play_repeat = True

        self.repeat_btn = QtWidgets.QPushButton('Repeat', clicked=self.repeat)
        self.box.addWidget(self.qsl, 2, 0, 1, 3)
        self.box.addWidget(self.repeat_btn, 3, 0, 1, 3)

        self.play_pause = True
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.play_mode)
        self.timer.start(1000)

    def play_mode(self):
        if self.play_pause == False:
            self.qsl.setMinimum(0)
            self.qsl.setMaximum(self.player.duration())
            self.qsl.setValue(self.qsl.value() + 1000)

    def slider_released(self):
        self.player.setPosition(self.qsl.value())

    def set_play_position(self, val):
        pass

    def play(self, song):
        if self.song != song:
            self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl(song)))
            self.song = song
            self.player.play()
            self.play_pause = False
            self.qsl.setEnabled(True)
            self.dict[song][0].setText("Pause")
        else:
            if self.play_pause == True:
                self.player.play()
                self.play_pause = False
                self.qsl.setEnabled(True)
                self.dict[song][0].setText("Pause")
            else:
                self.player.pause()
                self.play_pause = True
                self.dict[song][0].setText("Play")

    def player_state(self, state):
        if state == 0:
            self.play_pause = True
            self.qsl.setSliderPosition(0)
            self.qsl.setEnabled(False)
            if self.play_repeat == True:
                self.qsl.setEnabled(True)          
                self.play_pause = False
                self.player.play()

    def repeat(self):
        if self.play_repeat == False:
            self.play_repeat = True
            self.repeat_btn.setText("Repeat")   
        else:
            self.play_repeat = False
            self.repeat_btn.setText("Not Repeat")


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle('MP3-player, PyQt5')
    window.show()
    sys.exit(app.exec_())

Ответы (2 шт):

Автор решения: S. Nick

Я отметил строки, которые добавил. Попробуйте, если что не так напишите.

from PyQt5 import QtCore, QtWidgets, QtGui, QtMultimedia

class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.dict = {
            'D:/_Qt/__Qt/sound/sound_ringtimer.mp3': [],
            'D:/_Qt/EXE/Mp3/new_build/QThread_mp3/img/zvuki_prirody.mp3': []
        }
        self.song = ''

        self.player = QtMultimedia.QMediaPlayer()
        self.player.stateChanged.connect(self.player_state)

        self.qsl = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.qsl.sliderMoved[int].connect(self.set_play_position)
        self.qsl.sliderReleased.connect(self.slider_released)
        self.qsl.setEnabled(False)

        self.box = QtWidgets.QGridLayout(self)

        for line, song in enumerate(self.dict):           
            play_btn = QtWidgets.QPushButton('Play', clicked = lambda ch, song = song: self.play(song))

            label = QtWidgets.QLabel(song)
            self.box.addWidget(play_btn, line, 0)
            self.box.addWidget(label, line, 2)

            self.dict[song].append(play_btn)

        self.play_repeat = True

        self.repeat_btn = QtWidgets.QPushButton('Repeat', clicked=self.repeat)
        self.box.addWidget(self.qsl, 2, 0, 1, 3)
        self.box.addWidget(self.repeat_btn, 3, 0, 1, 3)

        self.play_pause = True
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.play_mode)
        self.timer.start(1000)

    def play_mode(self):
        if self.play_pause == False:
            self.qsl.setMinimum(0)
            self.qsl.setMaximum(self.player.duration())
            self.qsl.setValue(self.qsl.value() + 1000)

    def slider_released(self):
        self.player.setPosition(self.qsl.value())

    def set_play_position(self, val):
        pass

    def play(self, song):
        if self.song != song:
            self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl(song)))
            self.song = song
            self.player.play()
            self.play_pause = False
            self.qsl.setEnabled(True)
            self.dict[song][0].setText("Pause")
        else:
            if self.play_pause == True:
                self.player.play()
                self.play_pause = False
                self.qsl.setEnabled(True)
                self.dict[song][0].setText("Pause")
            else:
                self.player.pause()
                self.play_pause = True
                self.dict[song][0].setText("Play")

    def player_state(self, state):
        if state == 0:
            self.dict[self.song][0].setText("Play")                       # +++
            self.play_pause = True
            self.qsl.setSliderPosition(0)
            self.qsl.setEnabled(False)

            if self.play_repeat == True:
                self.qsl.setEnabled(True)          
                self.play_pause = False
                self.player.play()

                self.dict[self.song][0].setText("Play")                   # +++

        elif state == 1:                                                  # +++
            QtCore.QTimer.singleShot(
                10,
                lambda: self.dict[self.song][0].setText("Pause")
            ) 

    def repeat(self):
        if self.play_repeat == False:
            self.play_repeat = True
            self.repeat_btn.setText("Repeat")   
        else:
            self.play_repeat = False
            self.repeat_btn.setText("Not Repeat")


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle('MP3-player, PyQt5')
    window.show()
    sys.exit(app.exec_())
→ Ссылка
Автор решения: MAXIM045
from PyQt5 import QtCore, QtWidgets, QtGui, QtMultimedia

class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.dict = {
            '1.Papercut.mp3': [],
            '13.Numb.mp3': []
        }
        self.song = ''

        self.player = QtMultimedia.QMediaPlayer()
        self.player.stateChanged.connect(self.player_state)

        self.qsl = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.qsl.sliderMoved[int].connect(self.set_play_position)
        self.qsl.sliderReleased.connect(self.slider_released)
        self.qsl.setEnabled(False)

        self.box = QtWidgets.QGridLayout(self)

        for line, song in enumerate(self.dict):           
            play_btn = QtWidgets.QPushButton('Play', clicked = lambda ch, song = song: self.play(song))

            label = QtWidgets.QLabel(song)
            self.box.addWidget(play_btn, line, 0)
            self.box.addWidget(label, line, 2)

            self.dict[song].append(play_btn)

        self.play_repeat = True

        self.repeat_btn = QtWidgets.QPushButton('Repeat', clicked=self.repeat)
        self.box.addWidget(self.qsl, 2, 0, 1, 3)
        self.box.addWidget(self.repeat_btn, 3, 0, 1, 3)

        self.play_pause = True
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.play_mode)
        self.timer.start(1000)

    def play_mode(self):
        if self.play_pause == False:
            self.qsl.setMinimum(0)
            self.qsl.setMaximum(self.player.duration())
            self.qsl.setValue(self.qsl.value() + 1000)

    def slider_released(self):
        self.player.setPosition(self.qsl.value())

    def set_play_position(self, val):
        pass

    def play(self, song):
        if self.song != song:
            if self.player.isAudioAvailable() == True:
                self.dict[self.song][0].setText("Play")
            self.player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl(song)))
            self.song = song
            self.player.play()
            self.play_pause = False
            self.qsl.setEnabled(True)
            self.dict[song][0].setText("Pause")
        else:
            if self.play_pause == True:
                self.player.play()
                self.play_pause = False
                self.qsl.setEnabled(True)
                self.dict[song][0].setText("Pause")
            else:
                self.player.pause()
                self.play_pause = True
                self.dict[song][0].setText("Play")

    def player_state(self, state):
        if state == 0:
            self.play_pause = True
            self.qsl.setSliderPosition(0)
            self.qsl.setEnabled(False)
            self.dict[self.song][0].setText("Play")   # +++
            if self.play_repeat == True:
                self.qsl.setEnabled(True)          
                self.play_pause = False
                self.player.play()

    def repeat(self):
        if self.play_repeat == False:
            self.play_repeat = True
            self.repeat_btn.setText("Repeat")   
        else:
            self.play_repeat = False
            self.repeat_btn.setText("Not Repeat")


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle('MP3-player, PyQt5')
    window.show()
    sys.exit(app.exec_())
→ Ссылка