1

I have a largeish application I'm developing in Python3 using PyQt5. I want to do something very much like what is being done here in PyQt4:

# -*- coding: utf-8 -*-
import atexit

from PyQt4.QtCore import *
from PyQt4.QtGui import *


class XTerm(QX11EmbedContainer):

    def __init__(self, parent, xterm_cmd="xterm"):
        QX11EmbedContainer.__init__(self, parent)
        self.xterm_cmd = xterm_cmd
        self.process = QProcess(self)
        self.connect(self.process,
                     SIGNAL("finished(int, QProcess::ExitStatus)"),
                     self.on_term_close)
        atexit.register(self.kill)

    def kill(self):
        self.process.kill()
        self.process.waitForFinished()

    def sizeHint(self):
        size = QSize(400, 300)
        return size.expandedTo(QApplication.globalStrut())

    def show_term(self):
        args = [
            "-into",
            str(self.winId()),
            "-bg",
            "#000000",  # self.palette().color(QPalette.Background).name(),
            "-fg",
            "#f0f0f0",  # self.palette().color(QPalette.Foreground).name(),
            # border
            "-b", "0",
            "-w", "0",
            # blink cursor
            "-bc",
        ]
        self.process.start(self.xterm_cmd, args)
        if self.process.error() == QProcess.FailedToStart:
            print "xterm not installed"

    def on_term_close(self, exit_code, exit_status):
        print "close", exit_code, exit_status
        self.close()

(from https://bitbucket.org/henning/pyqtwi...11/terminal.py)

  • which is: Embed an X11 shell terminal (xterm) into a tab of my application.

I understand that QX11EmbedContainer is not in PyQt5, and that some usage of createWindowContainer may be the new approach, but I cannot find any example of this in action to follow.

I would ideally like to see the above code ported to a fully functional example using PyQt5 conventions and methods, but any assistance in any form will be helpful.

I have looked at Embedding external program inside pyqt5, but there is only a win32 solution there, and I need to run on Linux and MacOS, with windows being an unnecessary nicety, if there was a generalized solution to fit all 3. It feels like this is close, but I cannot find the appropriate replacement for the win32gui module to use in a general implementation.

I have looked at example of embedding matplotlib in PyQt5 1, but that pertains to matplotlib in particular, and not the general case.

All pointers and help will be gratefully acknowledged.

Caleb Howard
  • 45
  • 1
  • 6
  • 1
    Spyder IDE has IPython console inside it, and it is written in PyQt5. Maybe you can look in here: https://github.com/spyder-ide/spyder/blob/master/spyder/widgets/ipythonconsole/shell.py – mahesh Jul 30 '18 at 08:08
  • 1
    Basically, IDEs written in PyQt5 may be the best places to look, since they almost invariably need to embed terminal applications and the such on all platforms. – mahesh Jul 30 '18 at 08:16
  • 1
    The pyqt5 example works fine for me on linux. Just remove all the win32 junk and set `hwnd` to an appropriate window id. Your real question is: "how do I find the window id of an external application"? There are plenty of tools available on linux for doing that, and you already have a working example for windows. I have no idea about macos, though. – ekhumoro Jul 30 '18 at 09:14
  • These are great pointers! Thanks. @ekhumoro - I have been trying what you suggest (prior to posting the question) - using 'xwininfo' on MacOS (which is very like *NIX flavours) to get the window ID of a running xterm instance. No luck yet. Could you post the modified code you got working, please? – Caleb Howard Jul 30 '18 at 17:33
  • @mahesh - while Spyder does indeed incorporate a terminal shell, it appears to do so with a full implementation of a terminal, where I want to just drop in an external xwindows app, like xterm - without implementing the whole thing. – Caleb Howard Jul 30 '18 at 17:58
  • @CalebHoward. Modified code? You mean like `QWindow.fromWinId(0x2e00018)`? That will work on linux, but I have no idea whether anything so simple will work on macos. Did `QX11EmbedContainer` work on macos? – ekhumoro Jul 30 '18 at 20:42
  • @ekhumoro Yeah - like that. :-) That's what I was doing (essentially) - with the result being `*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSTaggedDate window]: unrecognized selector sent to instance 0x60000d'` So I guess it's not working under MacOS. Still looking for a solution, then. Back-burnering the feature for now. – Caleb Howard Jul 30 '18 at 23:31
  • @ekhumoro I tried the same in Linux mentioned here `(https://stackoverflow.com/questions/41474647/run-a-foreign-exe-inside-a-python-gui-pyqt)`. For some application, it is coming without any issues but others, such as Rviz, when run as a Qprocess, the whole window is not showing. Only a part is showing. Any idea why ? – Sid133 Jan 23 '20 at 12:54
  • @Sid133 Qt doesn't really support embedding *external* windows: see my comments [here](https://stackoverflow.com/questions/58816766/how-to-embed-a-pptk-viewer-in-a-pyqt5-window#comment104172619_58937338). – ekhumoro Jan 23 '20 at 17:11

0 Answers0