@AlikhanPython
Учу программирование на Python.

При воспроизведении pyttsx3 программа зависает. Что делать?

Всем привет! Я делаю программу на python с графическим интерфейсом для синтеза текста в речь (также есть функция сохранения аудиофайла и выбора голоса). У меня возникла какая-то проблема. При нажатии на кнопку слушать (то есть воспроизведения текста голосом бота) программа останавливается пока не закончится воспроизведение (тобиш нельзя нажимать кнопки и т.д). <— Это случается если я просто запускаю скрипт нажав на него. Но при запуске в PyCharm все прекрасно работает. При воспроизведении можно нажимать кнопки и дальше взаимодействовать с программа.

Для решения решил использовать многопоточность но при его использовании возникала ошибка.

P.S Для синтеза речи использовал pyttsx3

Подробнее с видеоматериалами -

Код:
import os
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox, QFileDialog
import pyttsx3
import re
from os import chdir

# Replace way with just in case
chdir(u"{0}".format(os.getcwd().replace("/", "\\")))

engine = pyttsx3.init() # pyttsx3 initialization

# Get system voices
voices = engine.getProperty("voices")
voicesList = []
[voicesList.append(voice.name) for voice in voices]

class UiMainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(790, 618)
        MainWindow.setMinimumSize(QtCore.QSize(790, 618))
        MainWindow.setMaximumSize(QtCore.QSize(790, 618))
        MainWindow.setStyleSheet("")
        MainWindow.setWindowIcon(QtGui.QIcon("icons\\window_icon.png"))

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.textEdit = QtWidgets.QPlainTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(20, 80, 751, 311))
        self.textEdit.setObjectName("text")

        self.windowLabel = QtWidgets.QLabel(self.centralwidget)
        self.windowLabel.setGeometry(QtCore.QRect(280, 10, 241, 31))
        font = QtGui.QFont()
        font.setFamily("Zelek")
        font.setPointSize(18)
        self.windowLabel.setFont(font)
        self.windowLabel.setObjectName("windowLabel")

        self.choiceVoice = QtWidgets.QComboBox(self.centralwidget)
        self.choiceVoice.setGeometry(QtCore.QRect(170, 430, 461, 41))
        self.choiceVoice.setAccessibleDescription("")
        self.choiceVoice.setCurrentText("")
        self.choiceVoice.setIconSize(QtCore.QSize(32, 32))
        self.choiceVoice.setObjectName("selectVoice")
        self.choiceVoice.addItems(voicesList)
        self.choiceVoice.setCurrentIndex(0)

        self.choiceSaveFileButton = QtWidgets.QPushButton(self.centralwidget)
        self.choiceSaveFileButton.setGeometry(QtCore.QRect(170, 550, 461, 41))
        font = QtGui.QFont()
        font.setFamily("Zelek")
        font.setPointSize(15)
        font.setBold(True)
        font.setWeight(75)
        self.choiceSaveFileButton.setFont(font)
        self.choiceSaveFileButton.setObjectName("selectDirectoryButton")

        self.textLabel = QtWidgets.QLabel(self.centralwidget)
        self.textLabel.setGeometry(QtCore.QRect(330, 50, 131, 21))
        font = QtGui.QFont()
        font.setFamily("Zelek")
        font.setPointSize(10)
        self.textLabel.setFont(font)
        self.textLabel.setStyleSheet("")
        self.textLabel.setAlignment(QtCore.Qt.AlignCenter)
        self.textLabel.setObjectName("textLabel")

        self.voiceLabel = QtWidgets.QLabel(self.centralwidget)
        self.voiceLabel.setGeometry(QtCore.QRect(220, 400, 350, 21))
        font = QtGui.QFont()
        font.setFamily("Zelek")
        font.setPointSize(10)
        self.voiceLabel.setFont(font)
        self.voiceLabel.setStyleSheet("")
        self.voiceLabel.setAlignment(QtCore.Qt.AlignCenter)
        self.voiceLabel.setObjectName("voiceLabel")

        self.listenButton = QtWidgets.QPushButton(self.centralwidget)
        self.listenButton.setGeometry(QtCore.QRect(170, 490, 461, 41))
        font = QtGui.QFont()
        font.setFamily("Zelek")
        font.setPointSize(15)
        self.listenButton.setFont(font)
        self.listenButton.setObjectName("pushButton")

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 790, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.choiceVoice.setCurrentIndex(-1)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.addFunctional()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Синтез текста в речь"))
        self.windowLabel.setText(_translate("MainWindow", "Синтез текста в речь"))
        self.choiceSaveFileButton.setText(_translate("MainWindow", "Сохранить аудиофайл"))
        self.textLabel.setText(_translate("MainWindow", "Введите ваш текст"))
        self.voiceLabel.setText(_translate("MainWindow", "Выберите голос (установленный на вашей системе)"))
        self.listenButton.setText(_translate("MainWindow", "Слушать"))

    def addFunctional(self):
        def start():
            saveFile = QFileDialog.getSaveFileName(filter=".mp3")[0]

            if saveFile != "":
                if not saveFile.endswith(".mp3"):
                    saveFile += ".mp3"

            text = self.textEdit.toPlainText()
            voiceName = self.choiceVoice.currentText()

            errorMessage = QMessageBox()
            errorMessage.setIcon(QMessageBox.Warning)
            errorMessage.setWindowTitle("Ошибка!")

            if (text == "" or [text] == re.findall("[ ]+", text) or voiceName == "" or saveFile == ""):
                if text == "" or [text] == re.findall("[ ]+", text):
                    errorMessage.setText("Введите текст в поле для ввода текста!")
                    errorMessage.exec_()
                elif voiceName == "":
                    errorMessage.setText("Выберите голос установленный на вашей системе!")
                    errorMessage.exec_()
                elif saveFile == "":
                    errorMessage.setText("Выберите куда сохранять файл!")
                    errorMessage.exec_()
            else:
                voices = engine.getProperty("voices")

                for voice in voices:
                    if voice.name == voiceName:
                        engine.setProperty("voice", voice.id)
                        break

                engine.save_to_file(text, saveFile)
                engine.runAndWait()

                message = QMessageBox()
                message.setIcon(QMessageBox.Information)
                message.setWindowTitle("Операция успешно выполнена!")
                message.setText(f"Операция успешно выполнена! Аудиофайл сохранен.\nЕсли вы ничего не услышали, то возможно выбранный\nвами голос не поддерживает тот, или иной язык.")

                message.exec_()

        def listenOrStopListenText():
            if self.listenButton.text() == "Слушать":
                text = self.textEdit.toPlainText()
                voiceName = self.choiceVoice.currentText()

                voices = engine.getProperty("voices")

                for voice in voices:
                    if voice.name == voiceName:
                        engine.setProperty("voice", voice.id)
                        break

                self.listenButton.setText("Остановить")

                engine.say(text)
                engine.runAndWait()

                self.listenButton.setText("Слушать")
            elif self.listenButton.text() == "Остановить":
                engine.stop()

        self.listenButton.clicked.connect(listenOrStopListenText)
        self.choiceSaveFileButton.clicked.connect(start)

# Application launch
if __name__ == "__main__":
    application = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = UiMainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(application.exec_())
  • Вопрос задан
  • 134 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы