In this article we are going to learn that How to Build Text to Speech App with Python & PyQt5, for this we want to use QtTextToSpeech module, the QtTextToSpeech module enables a PyQt application to support accessibility features such as text-to-speech, which is useful for end users who are visually challenged or cannot access the application for whatever reason. In which case the application can read out the relevant text.
First of all open your Qt Designer, by default we don’t have Qt Designer in PyQt5, you need to install PyQt5 Tools.
1 |
pip install pyqt5-tools |
Now we want to design our simple app for Text to Speech App.
- Add QLabel, QLineEdit and a QPushButton, after that add Horizontal Layout
- Add Another QLabel with QComboBox and make the layout Horizontally
- Add Another QLabel with QSlider and make the layout Horizontally
- At the end make the main window layout as vertically
This is the design at the end.

After that save your file in your working directory, it will be a .UI extension and now let’s convert our UI file to PY file.
1 |
pyuic5 -x TextToSpeech.ui -o TextToSpeech.py |
This is the code for creating the engine and also finding the available voices for the engine.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
self.engine = None engineNames = QTextToSpeech.availableEngines() if len(engineNames) > 0: engineName = engineNames[0] self.engine = QTextToSpeech(engineName) self.engine.stateChanged.connect(self.stateChanged) self.voices = [] for voice in self.engine.availableVoices(): self.voices.append(voice) self.comboBox.addItem(voice.name()) else: self.pushButton.setEnabled(False) |
Now let’s create our stateChanged method, we have connected this at the top.
1 |
self.engine.stateChanged.connect(self.stateChanged) |
This is the method that we have connected this with clicked signal of the QPushButton.
1 2 3 4 5 |
def say(self): self.pushButton.setEnabled(False) self.engine.setVoice(self.voices[self.comboBox.currentIndex()]) self.engine.setVolume(float(self.horizontalSlider.value() / 100)) self.engine.say(self.lineEdit.text()) |
And this is the complete code for the article.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtWidgets import QMainWindow from PyQt5.QtTextToSpeech import QTextToSpeech class Ui_MainWindow(QMainWindow): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(658, 236) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout_2.setObjectName("verticalLayout_2") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.label = QtWidgets.QLabel(self.centralwidget) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.label.setFont(font) self.label.setObjectName("label") self.horizontalLayout.addWidget(self.label) self.lineEdit = QtWidgets.QLineEdit(self.centralwidget) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.lineEdit.setFont(font) self.lineEdit.setObjectName("lineEdit") self.horizontalLayout.addWidget(self.lineEdit) self.pushButton = QtWidgets.QPushButton(self.centralwidget) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.pushButton.setFont(font) self.pushButton.setObjectName("pushButton") self.pushButton.clicked.connect(self.say) self.horizontalLayout.addWidget(self.pushButton) self.verticalLayout.addLayout(self.horizontalLayout) spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.label_2 = QtWidgets.QLabel(self.centralwidget) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.label_2.setFont(font) self.label_2.setObjectName("label_2") self.horizontalLayout_2.addWidget(self.label_2) self.comboBox = QtWidgets.QComboBox(self.centralwidget) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.comboBox.setFont(font) self.comboBox.setObjectName("comboBox") self.horizontalLayout_2.addWidget(self.comboBox) self.verticalLayout.addLayout(self.horizontalLayout_2) spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem1) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.label_3 = QtWidgets.QLabel(self.centralwidget) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.label_3.setFont(font) self.label_3.setObjectName("label_3") self.horizontalLayout_3.addWidget(self.label_3) self.horizontalSlider = QtWidgets.QSlider(self.centralwidget) self.horizontalSlider.setProperty("value", 40) self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) self.horizontalSlider.setObjectName("horizontalSlider") self.horizontalLayout_3.addWidget(self.horizontalSlider) self.verticalLayout.addLayout(self.horizontalLayout_3) self.verticalLayout_2.addLayout(self.verticalLayout) MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) self.engine = None engineNames = QTextToSpeech.availableEngines() if len(engineNames) > 0: engineName = engineNames[0] self.engine = QTextToSpeech(engineName) self.engine.stateChanged.connect(self.stateChanged) self.voices = [] for voice in self.engine.availableVoices(): self.voices.append(voice) self.comboBox.addItem(voice.name()) else: self.pushButton.setEnabled(False) def say(self): self.pushButton.setEnabled(False) self.engine.setVoice(self.voices[self.comboBox.currentIndex()]) self.engine.setVolume(float(self.horizontalSlider.value() / 100)) self.engine.say(self.lineEdit.text()) def stateChanged(self, state): if(state == QTextToSpeech.State.Ready): self.pushButton.setEnabled(True) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "Text To Speech")) self.label.setText(_translate("MainWindow", "Text:")) self.pushButton.setText(_translate("MainWindow", "Say")) self.label_2.setText(_translate("MainWindow", "Voices:")) self.label_3.setText(_translate("MainWindow", "Volume:")) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) MainWindow = QtWidgets.QMainWindow() ui = Ui_MainWindow() ui.setupUi(MainWindow) MainWindow.show() sys.exit(app.exec_()) |
Run the complete code and you will receive this kind of UI with Text to Speech functionality in Python and PyQt5.

Learn More on TKinter
- PyQt5 QTableWidget Tutorial: Create a Dynamic Table
- Create GUI Applications with Python & TKinter
- Python TKinter Layout Management
- How to Create Label in TKinter
- How to Create Buttin in Python TKinter
- Build Music Player in Python TKinter
- Python GUI Programming with TKinter
- TKinter VS PyQt, Which one is Good
- Creating Custom Widgets in TKinter