LooksForFuture
LooksForFuture

Reputation: 116

how to connect stdin of a subprocess to a qlineedit in python

I am building a kind of terminal in pyqt5 which you can run a python file from it and it shows you the output.

this is my code

import sys
from subprocess import Popen,PIPE

from PyQt5.QtWidgets import (QApplication,QWidget,QVBoxLayout,
                             QHBoxLayout,QPlainTextEdit,QLabel,
                             QLineEdit)

class Terminal(QWidget):
    def __init__(self):
        super().__init__()
        lay = QHBoxLayout()
        layout = QVBoxLayout()
        self.setLayout(layout)

        self.out = QPlainTextEdit()
        self.inLbl = QLabel('')
        self.inBar = QLineEdit()

        lay.addWidget(self.inLbl)
        lay.addWidget(self.inBar)

        layout.addWidget(self.out)
        layout.addLayout(lay)
    def runFile(self,url):
        self.out.clear()
        p = Popen(['python',url],stdout = PIPE,stderr = PIPE)
        stdout,stderr = p.communicate()
        err = stderr.decode()

        self.out.insertPlainText(stdout.decode())

        if err != '':
            self.out.insertPlainText('\n'+stderr.decode())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Terminal()
    window.runFile('test.py')
    window.show()
    sys.exit(app.exec_())

and this is test.py:

print('Hello '+name+'.')

I want when the terminal runs the file the self.inLbl changes to the string of input command and self.inBar gets input and returns the input and the self.out writes the text of self.inLbl plus input string.

How can I do that?

Upvotes: 1

Views: 554

Answers (1)

eyllanesc
eyllanesc

Reputation: 243907

In this case it is best to use QProcess instead of subprocess.Popen() since it can be easily written using the write() method. On the other hand, test.py must be modified so that it can receive information, input or a similar function must be used:

import sys

from PyQt5 import QtCore, QtWidgets


class Terminal(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()

        self.out = QtWidgets.QPlainTextEdit(readOnly=True)
        self.inBar = QtWidgets.QLineEdit()

        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.out)
        layout.addWidget(self.inBar)

        self.process = QtCore.QProcess(self)
        self.process.setProgram(sys.executable)
        self.process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
        self.process.readyReadStandardError.connect(self.on_readyReadStandardError)
        self.inBar.editingFinished.connect(self.on_editingFinished)

    def runFile(self, url):
        self.process.setArguments([url])
        self.process.start()

    @QtCore.pyqtSlot()
    def on_readyReadStandardOutput(self):
        out = self.process.readAllStandardOutput().data().decode()
        self.out.insertPlainText(out)

    @QtCore.pyqtSlot()
    def on_readyReadStandardError(self):
        err = self.process.readAllStandardError().data().decode()
        self.out.insertPlainText("\n" + err)

    @QtCore.pyqtSlot()
    def on_editingFinished(self):
        self.process.write(self.inBar.text().encode() + b"\n")
        self.inBar.clear()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = Terminal()
    window.runFile("test.py")
    window.show()
    sys.exit(app.exec_())

test.py

while True:
    name = input()
    print('Hello '+name+'.')

Upvotes: 2

Related Questions