How to embed terminal inside PyQt5 application without QProcess?
Asked Answered
M

2

8

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

Mirza answered 11/9, 2018 at 6:33 Comment(0)
L
6

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_())
Lynx answered 11/9, 2018 at 6:48 Comment(12)
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()))]) ?Mirza
I ran the code with above change but I simply get a plain EmbTerminal tab. There is nothing in it.Mirza
@v1h5 Do you have xterm installed? to verify it, execute it in the terminal. Both methods work for me.Lynx
Yes I do have xterm installed but looks like something is failing. Please have a look at this screenshot. ibb.co/jYvZQUMirza
I am using MacOS High Sierra and Python3.7Mirza
@v1h5 execute xterm in your terminal. what is the output. I tested on Linux.Lynx
By simply firing xterm is giving me something as below : xterm: Xt error: Can't open display: xterm: DISPLAY is not setMirza
@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.Lynx
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 outputMirza
Let us continue this discussion in chat.Mirza
@v1h5 that command only embeds the terminal in the window, but first the terminal must be opened correctly, check the following: #37826594.Lynx
It has started working but terminal opens up in a different window and not inside the tab.Mirza
M
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

Monoculture answered 4/1, 2019 at 13:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.