1

I'm currently designing a GUI that runs an external function (called LinkedFunc below) which prints something into a QTextEdit widget. To do so, I took the sys.stdout stream and redirected it to the QTextEdit widget, following the instructions here:

Print out python console output to Qtextedit

It works as intended, except that when I close the GUI window - the code keeps running indefinitely.

When I kill the current command the kernel seems to just hang, and I have to restart it in order to run the code again.

How do I rectify this so that closing the window stops the program? Redirecting the sys.stdout was the most recent addition to the code, and is when it stopped closing as expected, so I assume it has something to do with that.

I'm very new to using PyQt and building GUIs so I realize there could be something simple I'm doing wrong.

import sys
import LinkedFunc
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication, QFileDialog, QTextEdit
from PyQt5 import QtCore, QtGui


class Stream(QtCore.QObject):
    newText = QtCore.pyqtSignal(str)

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


class GenOutput(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()

        # Custom output stream.
        sys.stdout = Stream(newText=self.onUpdateText)

    def onUpdateText(self, text):
        # Print to text box widget.
        cursor = self.process.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        cursor.insertText(text)
        self.process.setTextCursor(cursor)
        self.process.ensureCursorVisible()

    def __del__(self):
        # Return stdout to defaults.
        sys.stdout = sys.__stdout__

    def initUI(self):

        # Button for generating the master list.
        btnGenOutput = QPushButton("Generate Output", self)
        btnGenOutput.move(30, 50)

        # Link the buttons to their function calls.
        btnGenOutput.clicked.connect(self.genOutputClicked)

        # Create the output widget.
        self.process = QTextEdit(self, readOnly=True)
        self.process.ensureCursorVisible()
        self.process.setLineWrapColumnOrWidth(500)
        self.process.setLineWrapMode(QTextEdit.FixedPixelWidth)
        self.process.setFixedWidth(400)
        self.process.setFixedHeight(150)
        self.process.move(30, 100)

        # Set window size and title, then show the window.
        self.setGeometry(300, 300, 500, 300)
        self.setWindowTitle('Test Application')
        self.show()

    def genOutputClicked(self):
        # Run the GenerateMaster.py file.
        LinkedFunc.main()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    gui = GenOutput()
    sys.exit(app.exec_())

LinkedFunc is simply as follows:

def main():

    print('Hello world!')
eyllanesc
  • 235,170
  • 19
  • 170
  • 241

1 Answers1

1

Instead of resetting the value of sys.stdout in the __del__ method, you could do it in the closeEvent method.

class GenOutput(QMainWindow):

    def __init__(self):
        super().__init__()
        self.initUI()
        sys.stdout = Stream(newText=self.onUpdateText)

    def onUpdateText(self, text):
        # Print to text box widget.
        ...

    def closeEvent(self, event):
        # Return stdout to defaults.
        sys.stdout = sys.__stdout__
        super().closeEvent(event)

    def initUI(self):
        ...

    def genOutputClicked(self):
        # Run the GenerateMaster.py file.
        LinkedFunc.main()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241