我想将xterm
嵌入到pyqt4
窗口小部件中并与之通信。特别是我希望能够打印到它并在其上执行命令(这样它在执行命令后返回到正常的用户提示,就像普通的shell一样)。考虑以下最小的例子。我怎样才能使它发挥作用?
#!/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_())
答案 0 :(得分:4)
要将xterm
嵌入您的某个窗口,您应该使用:
-into windowId给定一个X窗口标识符(十进制整数),xterm会将其顶级shell小部件重新显示到该窗口。这是用的 将xterm嵌入其他应用程序中。
xterm
本身与已启动的shell(bash等)进行通信。所以,你必须找到一种方法来与已启动的shell进行对话。您可以通过xterm
标志将打开的文件描述符传递给-Sccn
:
此选项允许xterm用作现有程序的输入和输出通道,有时用于专门的应用程序
所以,我认为你必须创建你的bash,zsh实例,无论你想发送什么命令。然后将该子进程的stdout / stderr fd连接到xterm实例,并将stdin连接到主程序,然后将来自xterm的输入和要发送到bash的命令多路复用(这样它们就会被执行并且被执行显示在xterm)。
bash ----------------------> xterm
\--< your.py <----------/
urxvt
的联合帮助页显示urxvt
有一些类似的开关:
-embed windowid
告诉urxvt将其窗口嵌入已存在的窗口, 这使应用程序可以轻松嵌入终端。 [...] 这是一个简短的Gtk2-perl片段,说明了如何使用此选项(更长时间 示例在doc / embed中:my $ rxvt = new Gtk2 :: Socket;
$ rxvt-&gt; signal_connect_after(realize =&gt; sub { 我的$ xid = $ _ [0] - &gt; window-&gt; get_xid;
system“urxvt -embed $ xid&amp;”;
});
和
-pty-fd文件描述符
告诉urxvt不要执行任何命令或创建新的pty / tty对,而是使用给定的文件描述符作为tty master。如果您想将urxvt作为通用终端模拟器驱动而不必在其中运行程序,这将非常有用。以下是perl中的一个示例,说明了如何使用此选项(较长的示例&gt;位于doc / pty-fd中):
使用IO :: Pty;
使用Fcntl;my $ pty = new IO :: Pty;
fcntl $ pty,F_SETFD,0; #clear close-on-exec
系统“urxvt -pty-fd”。 (fileno $ pty)。 “&安培;”;
关闭$ pty;#现在与rxvt通信 我的$ slave = $ pty-&gt;奴隶;
while(){print $ slave“got \ n”}
要在python中打开一个PTY,pty
模块看起来很有希望:http://docs.python.org/2/library/pty.html
有趣的阅读:http://sqizit.bartletts.id.au/2011/02/14/pseudo-terminals-in-python/