7

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

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
node_analyser
  • 1,502
  • 3
  • 17
  • 34

2 Answers2

5

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_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Is it ok if I use `self.process.start('xterm',['-into', str(int(self.winId()))])` instead of `self.process.start('urxvt',['-embed', str(int(self.winId()))])` ? – node_analyser Sep 11 '18 at 07:32
  • I ran the code with above change but I simply get a plain EmbTerminal tab. There is nothing in it. – node_analyser Sep 11 '18 at 07:35
  • @v1h5 Do you have xterm installed? to verify it, execute it in the terminal. Both methods work for me. – eyllanesc Sep 11 '18 at 07:43
  • Yes I do have xterm installed but looks like something is failing. Please have a look at this screenshot. https://ibb.co/jYvZQU – node_analyser Sep 11 '18 at 07:56
  • I am using MacOS High Sierra and Python3.7 – node_analyser Sep 11 '18 at 07:57
  • @v1h5 execute `xterm` in your terminal. what is the output. I tested on Linux. – eyllanesc Sep 11 '18 at 07:57
  • By simply firing `xterm` is giving me something as below : `xterm: Xt error: Can't open display: xterm: DISPLAY is not set` – node_analyser Sep 11 '18 at 07:58
  • @v1h5 So that's the problem, try to fix it, I do not have mac so I do not know how to fix it, review forums maybe find a solution. – eyllanesc Sep 11 '18 at 08:00
  • but I think xterm needs a display and that's why we pass `-into` with self.winId(). Checked whether self.winId() is proper or not. `print(int(self.winId()))` gives me proper output – node_analyser Sep 11 '18 at 08:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/179790/discussion-between-v1h5-and-eyllanesc). – node_analyser Sep 11 '18 at 08:01
  • 1
    @v1h5 that command only embeds the terminal in the window, but first the terminal must be opened correctly, check the following: https://stackoverflow.com/questions/37826094/xt-error-cant-open-display-if-using-default-display. – eyllanesc Sep 11 '18 at 08:01
  • It has started working but terminal opens up in a different window and not inside the tab. – node_analyser Sep 11 '18 at 09:19
3

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