Home > database >  stdout prints to PyQT text widget after function ends
stdout prints to PyQT text widget after function ends

Time:09-15

I found this solution, but it prints after function ends. When i press button_collect_data i'm calling print_sleep function. I expected that it would print each value after 1 sec sleep but it prints all after 3 second.

Main point that i want to see function progress, so

Question: What is the way to redirect stdout to some text widget in QT app to show every print immediately?

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        ...
        self.button_collect_data = QtWidgets.QPushButton(self.centralwidget)
        self.button_collect_data.setMaximumSize(QtCore.QSize(399, 16777215))
        self.button_collect_data.setObjectName("button_collect_data")
        ...
        self.console = QtWidgets.QTextEdit(self.centralwidget)
        self.console.setReadOnly(True)
        self.console.setObjectName("console")

        sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)
        self.add_functions()

    def add_functions(self):
        self.button_collect_data.clicked.connect(lambda: QtCore.QProcess(self.print_sleep()))

    def normalOutputWritten(self, text):
        """Append text to the QTextEdit."""
        # Maybe QTextEdit.append() works as well, but this is how I do it:
        cursor = self.console.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(text)
        self.console.setTextCursor(cursor)
        self.console.ensureCursorVisible()

    def print_sleep(self):
        for i in range(3):
            print(i)
            time.sleep(1)


class EmittingStream(QtCore.QObject):
    textWritten = QtCore.pyqtSignal(str)

    def write(self, text):
        self.textWritten.emit(str(text))


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_())

CodePudding user response:

I found solution which using QThread. Described here

For me it's working (but i don't know if it's the best) because in real case function is calling after pressing button from another module and i don't want change it somehow.

btw thanks @furas for idea of app.processEvents(). It's answering question, but not working in all cases. Especially with my code which i put in other question related with same app

  • Related