HinaKhadim
HinaKhadim

Reputation: 127

label text is not updated but only last line updated the label in pyqt5

I am making a project on pyqt5. now, its work is to click on one button "Click and Say" which call speech function in which label is updating and we say and it recognize it. the code is here.

from PyQt5 import QtCore, QtGui, QtWidgets
import urllib
import speech_recognition as sr
import time

def connected(host='http://google.com'):
    try:
        urllib.request.urlopen(host)
        return True
    except:
        return False




class Ui_Function(object):
    def setupUi(self, Function):
        Function.setObjectName("Function")
        Function.resize(737, 600)
        self.centralwidget = QtWidgets.QWidget(Function)
        self.centralwidget.setObjectName("centralwidget")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(50, 70, 601, 31))
        self.lineEdit.setObjectName("lineEdit")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(50, 30, 151, 17))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(320, 120, 67, 17))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(60, 150, 251, 21))
        self.label_3.setObjectName("label_3")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(60, 180, 101, 25))
        self.pushButton.setObjectName("pushButton")

        self.pushButton.clicked.connect(self.speech)

        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(60, 320, 601, 231))
        self.textEdit.setObjectName("textEdit")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(60, 290, 141, 21))
        self.label_4.setObjectName("label_4")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(570, 110, 89, 25))
        self.pushButton_2.setObjectName("pushButton_2")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(60, 220, 241, 21))
        self.label_5.setObjectName("label_5")
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setGeometry(QtCore.QRect(400, 180, 251, 31))
        self.comboBox.setObjectName("comboBox")
        Function.setCentralWidget(self.centralwidget)

        self.retranslateUi(Function)
        QtCore.QMetaObject.connectSlotsByName(Function)

    def retranslateUi(self, Function):
        _translate = QtCore.QCoreApplication.translate
        Function.setWindowTitle(_translate("Function", "MainWindow"))
        self.label.setText(_translate("Function", "Enter the Book Name:"))
        self.label_2.setText(_translate("Function", "OR"))
        self.label_3.setText(_translate("Function", "Write the Book Name by your Voice:"))
        self.pushButton.setText(_translate("Function", "Click and Say"))
        self.label_4.setText(_translate("Function", "Recommendations:"))
        self.pushButton_2.setText(_translate("Function", "Clear"))
        self.label_5.setText(_translate("Function", "TextLabel"))

    def speech(self):
        if connected():
            r = sr.Recognizer()
            with sr.Microphone() as source:
                r.adjust_for_ambient_noise(source)
                self.label_5.setText("Listening...")
                self.label_5.adjustSize()
                time.sleep(1)
    # read the audio data from the default microphone
                audio_data = r.listen(source,timeout=5)
                self.label_5.setText("Time over")
                time.sleep(1)
                self.label_5.setText("Recognizing...")
                time.sleep(1)
    # convert speech to text
                text = r.recognize_google(audio_data ,language='en-UK', show_all=True)
                try:
                    self.label_5.setText("You said:" )
                    list1=[]
                    self.comboBox.clear()
                    if (len(text)>0):
                        print(len(text["alternative"]))
                        for x in range(0,len(text["alternative"])):
                            list1.append(text["alternative"][x]["transcript"])
                        self.comboBox.addItems(list1)

                    else:
                        time.sleep(1)
                        self.label_5.setText("\tNothing")
                except LookupError:
                    time.sleep(1)
                    self.label_5.setText("Could not Understand Value")

                except sr.UnknownValueError:
                    time.sleep(1)
                    self.label_5.setText("Voice Recognition could not understand audio")

                except sr.RequestError as e:
                    time.sleep(1)
                    self.label_5.setText("Voice Recognition could not request results ; {0}".format(e))
        else:
            time.sleep(1)
            self.label_5.setText("NO Internet Connection. \nCheck your Internet Connection")
        time.sleep(1)
        self.label_5.setText("Completed")

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Function = QtWidgets.QMainWindow()
    ui = Ui_Function()
    ui.setupUi(Function)
    Function.show()
    sys.exit(app.exec_())

This code listens and recognize the word. but the only problem is that all labels are not updating in speech function. Only the last one which contains "completed" is updated. The flow of program is click on button and then it calls speech function which is listening, recognizing with updation of labels. I have even add time.sleep(1) before every updation. Any help will be appreciated. I am new to PYqt5.

Upvotes: 1

Views: 218

Answers (1)

eyllanesc
eyllanesc

Reputation: 244282

Tasks that consume a lot of time should not be executed in the GUI thread, instead you must execute it in another thread and send the information through signals.

from PyQt5 import QtCore, QtGui, QtWidgets
import urllib
import speech_recognition as sr
import threading
import time


def connected(host="http://google.com"):
    try:
        urllib.request.urlopen(host)
        return True
    except:
        return False


class Ui_Function(object):
    def setupUi(self, Function):
        Function.setObjectName("Function")
        Function.resize(737, 600)
        self.centralwidget = QtWidgets.QWidget(Function)
        self.centralwidget.setObjectName("centralwidget")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(50, 70, 601, 31))
        self.lineEdit.setObjectName("lineEdit")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(50, 30, 151, 17))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(320, 120, 67, 17))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(60, 150, 251, 21))
        self.label_3.setObjectName("label_3")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(60, 180, 101, 25))
        self.pushButton.setObjectName("pushButton")

        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(60, 320, 601, 231))
        self.textEdit.setObjectName("textEdit")
        self.label_4 = QtWidgets.QLabel(self.centralwidget)
        self.label_4.setGeometry(QtCore.QRect(60, 290, 141, 21))
        self.label_4.setObjectName("label_4")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(570, 110, 89, 25))
        self.pushButton_2.setObjectName("pushButton_2")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(60, 220, 241, 21))
        self.label_5.setObjectName("label_5")
        self.comboBox = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox.setGeometry(QtCore.QRect(400, 180, 251, 31))
        self.comboBox.setObjectName("comboBox")
        Function.setCentralWidget(self.centralwidget)

        self.retranslateUi(Function)
        QtCore.QMetaObject.connectSlotsByName(Function)

    def retranslateUi(self, Function):
        _translate = QtCore.QCoreApplication.translate
        Function.setWindowTitle(_translate("Function", "MainWindow"))
        self.label.setText(_translate("Function", "Enter the Book Name:"))
        self.label_2.setText(_translate("Function", "OR"))
        self.label_3.setText(
            _translate("Function", "Write the Book Name by your Voice:")
        )
        self.pushButton.setText(_translate("Function", "Click and Say"))
        self.label_4.setText(_translate("Function", "Recommendations:"))
        self.pushButton_2.setText(_translate("Function", "Clear"))
        self.label_5.setText(_translate("Function", "TextLabel"))


class SpeechWorker(QtCore.QObject):
    messageChanged = QtCore.pyqtSignal(str)
    itemsChanged = QtCore.pyqtSignal(list)

    def speech(self):
        threading.Thread(target=self._speech, daemon=True).start()

    def _speech(self):
        if connected():
            r = sr.Recognizer()
            with sr.Microphone() as source:
                r.adjust_for_ambient_noise(source)
                self.messageChanged.emit("Listening...")
                time.sleep(1)
                # read the audio data from the default microphone
                audio_data = r.listen(source, timeout=5)
                self.messageChanged.emit("Time over")
                time.sleep(1)
                self.messageChanged.emit("Recognizing...")
                time.sleep(1)
                # convert speech to text
                text = r.recognize_google(audio_data, language="en-UK", show_all=True)
                try:
                    self.messageChanged.emit("You said:")
                    self.itemsChanged.emit([])
                    list1 = []
                    if len(text) > 0:
                        print(len(text["alternative"]))
                        for x in range(0, len(text["alternative"])):
                            list1.append(text["alternative"][x]["transcript"])
                        self.itemsChanged.emit(list1)
                    else:
                        time.sleep(1)
                        self.messageChanged.emit("\tNothing")

                except LookupError:
                    time.sleep(1)
                    self.messageChanged.emit("Could not Understand Value")

                except sr.UnknownValueError:
                    time.sleep(1)
                    self.messageChanged.emit(
                        "Voice Recognition could not understand audio"
                    )

                except sr.RequestError as e:
                    time.sleep(1)
                    self.messageChanged.emit(
                        "Voice Recognition could not request results ; {0}".format(e)
                    )
        else:
            time.sleep(1)
            self.messageChanged.emit(
                "NO Internet Connection. \nCheck your Internet Connection"
            )
        time.sleep(1)
        self.messageChanged.emit("Completed")


class Function(QtWidgets.QMainWindow, Ui_Function):
    def __init__(self, parent=None):
        super(Function, self).__init__(parent)
        self.setupUi(self)

        self.worker = SpeechWorker()
        self.worker.messageChanged.connect(self.updateMessage)
        self.worker.itemsChanged.connect(self.updateItems)

        self.pushButton.clicked.connect(self.worker.speech)

    @QtCore.pyqtSlot(str)
    def updateMessage(self, message):
        self.label_5.setText(message)
        self.label_5.adjustSize()

    @QtCore.pyqtSlot(list)
    def updateItems(self, items):
        self.comboBox.clear()
        self.comboBox.addItems(items)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Function()
    w.show()
    sys.exit(app.exec_())

Upvotes: 1

Related Questions