0

Right now I can make a terminal but the output is not used as a command. It just prints a string to the virtual terminal.

from gi.repository import Gtk, GObject, Vte

class TheWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="inherited cell renderer")
        self.set_default_size(400, 200)

        box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        v = Vte.Terminal()
        #v.connect ("child-exited", lambda term: gtk.main_quit())
        length = len("echo \"string\"\n")
        v.feed("echo \"string\"\n", length)
        box.pack_start(v, True, True, 0)

        self.add(box)

I tried to use the docs here http://developer.gnome.org/vte/0.30/ , but I had some trouble figuring all that out. I couldn't find any documentation on vte for python gtk3 at all.

Mainly I'm just trying to figure out how to get the command prompt in the virtual terminal so it will accept commands from inside the python gtk3 interface.

Quentin Engles
  • 2,744
  • 1
  • 20
  • 33
  • Here is some more info about it http://askubuntu.com/questions/154354/how-to-add-vte-terminal-widget-in-gtk3 After following those instructions I was able to write commands in the terminal directly. Now I need to figure out how to do it from gtk. – Quentin Engles Aug 04 '12 at 10:46

1 Answers1

4

Here's the answer. :) The important parts are fork_command_full and feed_child.

from gi.repository import Gtk, GObject, Vte
#GObject is not required. I just import it everywhere just in case.
#Gtk, Vte, and GLib are required.
from gi.repository import GLib
import os
#os.environ['HOME'] helps to keep from hard coding the home string.
#os is not required unless you want that functionality.

class TheWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="inherited cell renderer")
        self.set_default_size(600, 300)
        self.terminal     = Vte.Terminal()
        self.terminal.fork_command_full(
                Vte.PtyFlags.DEFAULT, #default is fine
                os.environ['HOME'], #where to start the command?
                ["/bin/sh"], #where is the emulator?
                [], #it's ok to leave this list empty
                GLib.SpawnFlags.DO_NOT_REAP_CHILD,
                None, #at least None is required
                None,
                )
        #Set up a button to click and run a demo command
        self.button = Gtk.Button("Do The Command")
        #To get the command to automatically run
        #a newline(\n) character is used at the end of the
        #command string.
        self.command = "echo \"Sending this command to a virtual terminal.\"\n"
        command = Gtk.Label("The command: "+self.command)
        self.button.connect("clicked", self.InputToTerm)
        #end demo command code

        #set up the interface
        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        box.pack_start(self.button, False, True, 0)
        box.pack_start(command, False, True, 1)
        #a scroll window is required for the terminal
        scroller = Gtk.ScrolledWindow()
        scroller.set_hexpand(True)
        scroller.set_vexpand(True)
        scroller.add(self.terminal)
        box.pack_start(scroller, False, True, 2)
        self.add(box)

    def InputToTerm(self, clicker):
        #get the command when the button is clicked
        length = len(self.command)
        #A length is not required but is the easiest mechanism.
        #Otherwise the command must be null terminated.
        #Feed the command to the terminal.
        self.terminal.feed_child(self.command, length)


win = TheWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
Quentin Engles
  • 2,744
  • 1
  • 20
  • 33
  • The script works great but do you know if is there any way to avoid printing the commands? ex: `echo "Sending this command to a virtual terminal."` ? –  Aug 10 '14 at 16:42
  • I'm not sure what you mean. If you want to run commands that aren't printed you don't need a virtual terminal. Popen will do that. – Quentin Engles Aug 11 '14 at 01:01
  • ( i was asking about how to only print the output of commands in a vte, it is usefull for printing in real time)but i just find it how to do it. in the VTE terminal write `tty` in other to get `/dev/pts/#` and then the bash commands from other process can be redirected there by doing `echo 'foo' > /dev/pts/#` –  Aug 11 '14 at 01:57
  • Ask this as a question. Link to it here in a comment. I will answer it. – Quentin Engles Aug 11 '14 at 02:04
  • Ok. Do you not want the python code to do it for you? – Quentin Engles Aug 11 '14 at 02:05
  • Is there any better solution than the one of using `echo 'foo' > /dev/pts/# ` ? if not i think that is not worth to ask! –  Aug 11 '14 at 02:13
  • If you are satisfied with that then go with it. – Quentin Engles Aug 11 '14 at 02:17
  • 1
    the command will not be printed if contains non ascii chars. So, in one line: `self.terminal.feed_child(self.command, len(self.command.decode()))` – ilias iliadis Apr 23 '18 at 11:34
  • 2
    The function "fork_command_full" has been renamed to "spawn_sync" and is deprecated. – PizzaLovingNerd May 03 '20 at 04:09