How to embed terminal inside PyQt5 application without QProcess?

Viewed 7740

I have been struggling lately with embedding a terminal inside PyQt GUI app. Tried almost every search on Internet but nothing looks like of any help.

I have a QTabWidget and I simply need one tab to have a terminal.

Is it not at all possible to do so ?

Isn't there something like QTabWidget.Tab2.show(terminal-app) and default terminal gets displayed in tab2 and every function like ls, ifconfig, cd etc works fine ?

P.S - I have already tried these but no success. Embedding a terminal in PyQt5

(converted code here from PyQt4 to PyQt5 but this does not fulfill my needs) how to use a terminal embedded in a PyQt GUI

T.I.A

2 Answers

short answer: Qt5 does not provide the use of the terminal, so you will have to use QProcess.

TL;DR

The EmbTerminal class that is proposed as a solution is a widget so you must add it with addTab(), keep in mind that you must have installed the urxvt terminal (if you want to check your installation run urxvt in the terminal)

import sys
from PyQt5 import QtCore, QtWidgets


class EmbTerminal(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(EmbTerminal, self).__init__(parent)
        self.process = QtCore.QProcess(self)
        self.terminal = QtWidgets.QWidget(self)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.terminal)
        # Works also with urxvt:
        self.process.start('urxvt',['-embed', str(int(self.winId()))])
        self.setFixedSize(640, 480)


class mainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(mainWindow, self).__init__(parent)

        central_widget = QtWidgets.QWidget()
        lay = QtWidgets.QVBoxLayout(central_widget)
        self.setCentralWidget(central_widget)

        tab_widget = QtWidgets.QTabWidget()
        lay.addWidget(tab_widget)

        tab_widget.addTab(EmbTerminal(), "EmbTerminal")
        tab_widget.addTab(QtWidgets.QTextEdit(), "QTextEdit")
        tab_widget.addTab(QtWidgets.QMdiArea(), "QMdiArea")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main = mainWindow()
    main.show()
    sys.exit(app.exec_())

I've had the same problem for a few months now and the urxvt or xterm solution doesn't cut it for me, so I created a repo where I'm working on an easily embeddable terminal for PyQt5. It works for some commands but for commands like python it just has trouble writing into a running process like that.

Feel free to contribute! https://github.com/Fuchsiaff/PyQtTerminal

Related