--- a/eric7/Plugins/UiExtensionPlugins/Translator/TranslatorWidget.py Tue Aug 17 12:17:11 2021 +0200 +++ b/eric7/Plugins/UiExtensionPlugins/Translator/TranslatorWidget.py Tue Aug 17 12:17:56 2021 +0200 @@ -10,8 +10,7 @@ from PyQt6.QtCore import pyqtSlot, QTemporaryFile from PyQt6.QtWidgets import QWidget try: - # TODO: adapt QtMultiMedia usage for Qt 6.2 - from PyQt6.QtMultimedia import QMediaPlayer, QMediaContent + from PyQt6.QtMultimedia import QMediaFormat, QMediaPlayer, QAudioOutput MULTIMEDIA_AVAILABLE = True except ImportError: MULTIMEDIA_AVAILABLE = False @@ -35,9 +34,12 @@ """ Constructor - @param plugin reference to the plugin object (TranslatorPlugin) - @param translator reference to the translator object (Translator) - @param parent reference to the parent widget (QWidget) + @param plugin reference to the plugin object + @type TranslatorPlugin + @param translator reference to the translator object + @type Translator + @param parent reference to the parent widget + @type QWidget """ super().__init__(parent) self.setupUi(self) @@ -50,11 +52,18 @@ self.__translatorRequest = None self.__translationEngine = None + self.__audioOutput = None self.__mediaPlayer = None self.__mediaFile = None - audioAvailable = (MULTIMEDIA_AVAILABLE and - bool(QMediaPlayer.hasSupport("audio/mpeg"))) + audioAvailable = False + if MULTIMEDIA_AVAILABLE: + mediaFormat = QMediaFormat() + audioAvailable = ( + QMediaFormat.AudioCodec.MP3 in + mediaFormat.supportedAudioCodecs( + QMediaFormat.ConversionMode.Decode) + ) self.pronounceOrigButton.setVisible(audioAvailable) self.pronounceTransButton.setVisible(audioAvailable) @@ -136,7 +145,8 @@ """ Private method to return the code of the selected original language. - @return code of the original language (string) + @return code of the original language + @rtype str """ return self.origLanguageComboBox.itemData( self.origLanguageComboBox.currentIndex()) @@ -145,7 +155,8 @@ """ Private method to return the code of the selected translation language. - @return code of the translation language (string) + @return code of the translation language + @rtype str """ return self.transLanguageComboBox.itemData( self.transLanguageComboBox.currentIndex()) @@ -240,7 +251,8 @@ """ Private slot to handle the selection of the original language. - @param index current index (integer) + @param index current index + @type int """ self.__plugin.setPreferences( "OriginalLanguage", self.origLanguageComboBox.itemData(index)) @@ -276,7 +288,8 @@ """ Private slot to handle the selection of the translation language. - @param index current index (integer) + @param index current index + @type int """ self.__plugin.setPreferences( "TranslationLanguage", self.transLanguageComboBox.itemData(index)) @@ -369,11 +382,14 @@ """ Private method to translate the given text. - @param text text to be translated (string) - @param originalLanguage language code of the original (string) - @param translationLanguage language code of the translation (string) - @return tuple of translated text (string) and flag indicating - success (boolean) + @param text text to be translated + @type str + @param originalLanguage language code of the original + @type str + @param translationLanguage language code of the translation + @type str + @return tuple of translated text and flag indicating success + @rtype tuple of (str, bool) """ if self.__translatorRequest is None: from .TranslatorRequest import TranslatorRequest @@ -393,8 +409,10 @@ """ Private method to pronounce the given text. - @param text text to be pronounced (string) - @param language language code of the text (string) + @param text text to be pronounced + @type str + @param language language code of the text + @type str """ if not text or not language: return @@ -405,10 +423,18 @@ if self.__mediaPlayer is None: self.__mediaPlayer = QMediaPlayer(self) - self.__mediaPlayer.stateChanged.connect( - self.__mediaPlayerStateChanged) + self.__audioOutput = QAudioOutput(self) + self.__mediaPlayer.setAudioOutput(self.__audioOutput) + + self.__mediaPlayer.playbackStateChanged.connect( + self.__mediaPlayerPlaybackStateChanged) + self.__mediaPlayer.errorOccurred.connect( + self.__mediaPlayerError) - if self.__mediaPlayer.state() == QMediaPlayer.State.PlayingState: + if ( + self.__mediaPlayer.playbackState() == + QMediaPlayer.PlaybackState.PlayingState + ): return self.__ensureTranslationEngineReady() @@ -428,8 +454,11 @@ self.__mediaFile.open() self.__mediaFile.setAutoRemove(False) self.__mediaFile.write(data) + self.__mediaFile.close() - self.__mediaPlayer.setMedia(QMediaContent(), self.__mediaFile) + from PyQt6.QtCore import QUrl + self.__mediaPlayer.setSource( + QUrl.fromLocalFile(self.__mediaFile.fileName())) self.__mediaPlayer.play() else: EricMessageBox.critical( @@ -437,17 +466,36 @@ self.tr("Translation Error"), data) - def __mediaPlayerStateChanged(self, state): + @pyqtSlot(QMediaPlayer.PlaybackState) + def __mediaPlayerPlaybackStateChanged(self, state): """ Private slot handling changes of the media player state. - @param state media player state (QAudio.State) + @param state media player state (QMediaPlayer.PlaybackState) """ - if state == QMediaPlayer.State.StoppedState: + if state == QMediaPlayer.PlaybackState.StoppedState: self.__mediaFile.close() self.__mediaFile.remove() self.__mediaFile = None + @pyqtSlot(QMediaPlayer.Error, str) + def __mediaPlayerError(self, error, errorString): + """ + Private slot to handle errors during playback of the data. + + @param error media player error condition + @type QMediaPlayer.Error + @param errorString string representation for the error + @type str + """ + if error != QMediaPlayer.Error.NoError: + EricMessageBox.warning( + self, + self.tr("Error playing pronunciation"), + self.tr("<p>The received pronunciation could not be played." + "</p><p>Reason: {0}</p>") + ) + @pyqtSlot() def on_preferencesButton_clicked(self): """