Search code examples
pythonpyqtpyqt4

TextBrowser does not update text through connected process in PyQt4


I trying to create a program with PyQt4, where the user is prompted to give an answer to a question. If the answer is correct, a note that the answer is correct shall appear and a new question be generated. If the answer is incorrect, it should print out that line and then pose the same question again. A working example is:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import numpy as np
import time


class Window(QWidget):
    def __init__(self,parent=None):
        super(Window, self).__init__(parent)
        self.lineEdit = QLineEdit()
        self.textBrowser = QTextBrowser()
        layout = QVBoxLayout()
        layout.addWidget(self.textBrowser)
        layout.addWidget(self.lineEdit)
        self.setLayout(layout)
        self.lineEdit.setDisabled(False)
        self.go_outer()
    def go_outer(self):
        random_instance=["home","honey","micro"]
        random_corresponding=["depot","well","soft"]
        random_index=np.random.randint(0,3)
        self.ret=random_instance[random_index]
        self.corres=random_corresponding[random_index]
        self.go()
    def go(self):
        self.textBrowser.append(self.ret)
        self.lineEdit.returnPressed.connect(self.process)
    def process(self):
        userInput = self.lineEdit.text()
        if userInput == self.corres:
            self.textBrowser.append("Your answer is correct.")
            self.textBrowser.update()
            time.sleep(5)
            self.textBrowser.clear()
            self.go_outer()
        else:
            self.textBrowser.append("Your answer is incorrect. Please try again.")
            self.textBrowser.update()
            time.sleep(5)
            self.lineEdit.clear()
            self.textBrowser.clear()
            self.go()



def run():
    app=QApplication(sys.argv)
    GUI=Window()
    GUI.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    run()

The problem is, that it shows the text obtained from the outside function "get_text()", but does not show the "Your answer is correct" or "Your answer is incorrect. Please try again."

Any ideas why this is so and, consequently, how to solve it?


Solution

  • You only have to connect a signal once to the slot, so you must move it to the constructor.

    Another problem is that the sleep function is not GUI friendly, a good option is to use a timer, in this case we will use QTimer.singleShot(), and we will make some minor modifications.

    All of the above is implemented in the following code:

    class Window(QWidget):
        def __init__(self,parent=None):
            super(Window, self).__init__(parent)
            self.lineEdit = QLineEdit()
            self.textBrowser = QTextBrowser()
            layout = QVBoxLayout()
            layout.addWidget(self.textBrowser)
            layout.addWidget(self.lineEdit)
            self.setLayout(layout)
            self.lineEdit.setDisabled(False)
            self.go_outer()
            self.lineEdit.returnPressed.connect(self.process)
    
        def go_outer(self):
            random_instance=["home","honey","micro"]
            random_corresponding=["depot","well","soft"]
            random_index=np.random.randint(0,3)
            self.ret=random_instance[random_index]
            self.corres=random_corresponding[random_index]
            self.go()
    
        def go(self):
            self.textBrowser.clear()
            self.lineEdit.setDisabled(False)
            self.lineEdit.clear()
            self.textBrowser.append(self.ret)
    
        def process(self):
            userInput = self.lineEdit.text()
            self.lineEdit.setDisabled(True)
            if userInput == self.corres:
                self.textBrowser.append("Your answer is correct.")
                QTimer.singleShot(5000, self.go_outer)
            else:
                self.textBrowser.append("Your answer is incorrect. Please try again.")
                QTimer.singleShot(5000, self.go)