Embed xterm into QWidget and communicate with it

a 夏天 提交于 2019-12-10 09:59:14

问题


I want to embed an xterm into a pyqt4 widget and communicate with it. Especially I want to be able to print to it and execute commands on it (such that it returns to normal user prompt after executing the command just like a normal shell would do). Consider the following minimal example. How can I make it work?

#!/usr/bin/env python
#-*- coding:utf-8 -*-

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


class embedxterm(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        self.setMinimumWidth(900)
        self.setMinimumHeight(400)
        self.process = QProcess(self)

        self.terminal = QWidget(self)
        self.terminal.setMinimumHeight(300)

        self.cmd1 = QPushButton('Command1',self)
        self.cmd2 = QPushButton('Command2',self)
        self.hello = QPushButton('Print Hello World',self)

        layout = QVBoxLayout(self)

        layoutH = QHBoxLayout(self)

        layoutH.addWidget(self.cmd1)
        layoutH.addWidget(self.cmd2)
        layoutH.addWidget(self.hello)


        layout.addLayout(layoutH)
        layout.addWidget(self.terminal)


        self.process.start(
            'xterm',['-into', str(self.terminal.winId())])

        self.cmd1.clicked.connect(self.Ccmd1)
        self.cmd2.clicked.connect(self.Ccmd2)
        self.hello.clicked.connect(self.Chello)

    def Ccmd1(self):
        self.process.write('ls -l')
        # Should execute ls -l on this terminal

    def Ccmd2(self):
        self.process.write('ping www.google.com')
        # should execute ping www.google.com on this terminal

    def Chello(self):
        self.process.write('Hello World')
        # should just print "Hello World" on this terminal

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

回答1:


To embed a xterm into one of your windows you should use:

-into windowId Given an X window identifier (a decimal integer), xterm will reparent its top-level shell widget to that window. This is used to embed xterm within other applications.

xterm itself talks to the launched shell (bash etc). So, you have to find a way to talk to that launched shell. You can pass open filedescriptors to xterm via the -Sccn flag:

This option allows xterm to be used as an input and output channel for an existing program and is sometimes used in specialized applications

So, I think you have to create your instance of bash, zsh, whatever you want to send the commands to. Then connect the stdout/stderr fd of that subprocess to your instance of xterm and connect the stdin to your main program which then multiplexes the input coming from the xterm and the commands you want to send to the bash (so they will get executed and be shown in xterm).

bash ----------------------> xterm
    \--< your.py <----------/

The manpage of urxvt reveils that urxvt has some similar switches:

-embed windowid
Tells urxvt to embed its windows into an already-existing window, which enables applications to easily embed a terminal. [ ... ] Here is a short Gtk2-perl snippet that illustrates how this option can be used (a longer example is in doc/embed):

my $rxvt = new Gtk2::Socket;
$rxvt->signal_connect_after (realize => sub { my $xid = $_[0]->window->get_xid;
system "urxvt -embed $xid &";
});

and

-pty-fd file descriptor
Tells urxvt NOT to execute any commands or create a new pty/tty pair but instead use the given file descriptor as the tty master. This is useful if you want to drive urxvt as a generic terminal emulator without having to run a program within it.

Here is a example in perl that illustrates how this option can be used (a longer example > is in doc/pty-fd):

use IO::Pty;
use Fcntl;

my $pty = new IO::Pty;
fcntl $pty, F_SETFD, 0; # clear close-on-exec
system "urxvt -pty-fd " . (fileno $pty) . "&";
close $pty;

# now communicate with rxvt
my $slave = $pty->slave;
while () { print $slave "got \n" }

To open a PTY from within python the pty module looks promising: http://docs.python.org/2/library/pty.html

Interesting read: http://sqizit.bartletts.id.au/2011/02/14/pseudo-terminals-in-python/



来源:https://stackoverflow.com/questions/14772138/embed-xterm-into-qwidget-and-communicate-with-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!