Skip to content Skip to sidebar Skip to footer

Redirecting Stdout From A Secondary Thread (multithreading With A Function Instead Of Class?)

I am trying to get my stdout displayed on a QTextEdit made via Qt Designer (PyQt5). Actually I made it work yet it doesn't show the info at the same time it was made. Instead it wa

Solution 1:

For this case you can use the native threading of python:

import sys

import threading
import time

from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtGui import QTextCursor

from ui_form import Ui_Form


class EmittingStream(QObject):  # test
    textWritten = pyqtSignal(str)

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


class Form(QMainWindow):
    finished = pyqtSignal()
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)

        # Install the custom output stream
        sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)  # test

        self.ui = Ui_Form()
        self.ui.setupUi(self)

        self.ui.pushButton_text.clicked.connect(self.start_task)
        self.finished.connect(lambda: self.ui.pushButton_text.setEnabled(True))

    def start_task(self):
        var = self.ui.lineEdit.text()
        self.thread = threading.Thread(target=self.test_write, args=(args, ))
        self.thread.start()
        self.ui.pushButton_text.setEnabled(False)

    def __del__(self):  # test
        # Restore sys.stdout
        sys.stdout = sys.__stdout__

    def normalOutputWritten(self, text):  # test
        """Append text to the QTextEdit."""
        cursor = self.ui.textEdit.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.ui.textEdit.setTextCursor(cursor)
        self.ui.textEdit.ensureCursorVisible()

    def test_write(self, *args):
        var1 = args[0]
        print("something written")
        time.sleep(5) # simulate expensive task
        print("something written ----")
        self.finished.emit()


def main():
    app = QApplication(sys.argv)
    form = Form()
    form.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

Post a Comment for "Redirecting Stdout From A Secondary Thread (multithreading With A Function Instead Of Class?)"