在一个应用程序中,我想嵌入 VteTerminal 并让用户提供预定义的命令。
在我运行一个需要一些时间的命令后,我想运行另一个命令。但是,即使第一个命令还没有启动,第二个命令也会运行,或者看起来是这样。按钮标签立即更改为“已完成”,在终端中,您可以在第一个命令之后(在第一个命令回显文件之前)看到 echo 命令。
如何让 feed_child 等到命令完成?
以下是示例代码:
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Vte', '2.91')
from gi.repository import Gtk, GLib, Vte
from os import environ
class Terminal(Vte.Terminal):
def __init__(self):
super(Terminal, self).__init__()
self.connect_after('child-exited', self.on_child_exited)
self.create_child()
def create_child(self):
self.spawn_async(
Vte.PtyFlags.DEFAULT,
environ['HOME'],
["/bin/bash"],
[],
GLib.SpawnFlags.DO_NOT_REAP_CHILD,
None,
None,
-1,
None,
None,
None
)
def feed(self, command):
command += '\n'
self.feed_child(command.encode())
def on_child_exited(self, terminal, status):
# Create a new child if the user ended the current one
# with Ctrl-D or typing exit.
self.create_child()
class VteTest(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Vte Test")
self.connect('destroy', Gtk.main_quit)
self.terminal = Terminal()
self.set_default_size(600, 400)
# GtkBox
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
# VteTerminal
sw = Gtk.ScrolledWindow()
sw.add(self.terminal)
box.pack_start(sw, True, True, 2)
# GtkButton
self.btn = Gtk.Button(label="Run commands")
self.btn.connect("clicked", self.on_btn_clicked)
box.pack_start(self.btn, False, True, 2)
# Add GtkBox to window
self.add(box)
self.show_all()
def on_btn_clicked(self, widget):
self.terminal.feed('for F in $(ls); do echo "$F"; sleep 0.2; done')
# Button label is instantaniously changed to "Finished"
self.btn.set_label('Working...')
# TODO: wait until command has finished
self.terminal.feed('echo "This shoud be the end"')
self.btn.set_label('Finished')
VteTest()
Gtk.main()