Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to embed terminal inside PyQt5 application without QProcess?

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

like image 523
v1h5 Avatar asked Sep 11 '18 06:09

v1h5


People also ask

Is PyQt good for GUI?

PyQt5 is a very well-known GUI framework used by both Python coders and UI designers. One of its components, the PyQt package, is built around the Qt framework, which is a leading cross-platform GUI design tool for just about any kind of application.

Does PyQt require Qt?

You can purchase the commercial version of PyQt here. More information about licensing can be found in the License FAQ. PyQt does not include a copy of Qt. You must obtain a correctly licensed copy of Qt yourself.

Why use PyQt5?

PyQt is widely used for creating large-scale GUI-based programs. It gives programmers the freedom to create GUIs of their choice while also providing a lot of good pre-built designs. PyQT gives you widgets to create complex GUIs.


1 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_())
like image 71
eyllanesc Avatar answered Nov 14 '22 09:11

eyllanesc