Show terminal output in gui window using python gtk

I am developing software and I want a window in it that will display the output generated by the terminal (as the package manager does). For example, if I give the installation command, the installation process should be disabled in my window, and not in the terminal. Is there any way to do this in python gtk?

+4
source share
3 answers

If you are on Linux (as you claim), something like this should work:

import gtk import gobject import pango import os from subprocess import Popen, PIPE import fcntl wnd = gtk.Window() wnd.set_default_size(400, 400) wnd.connect("destroy", gtk.main_quit) textview = gtk.TextView() fontdesc = pango.FontDescription("monospace") textview.modify_font(fontdesc) scroll = gtk.ScrolledWindow() scroll.add(textview) exp = gtk.Expander("Details") exp.add(scroll) wnd.add(exp) wnd.show_all() sub_proc = Popen("ping -c 10 localhost", stdout=PIPE, shell=True) sub_outp = "" def non_block_read(output): fd = output.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) try: return output.read() except: return '' def update_terminal(): textview.get_buffer().insert_at_cursor(non_block_read(sub_proc.stdout)) return sub_proc.poll() is None gobject.timeout_add(100, update_terminal) gtk.main() 

A non-blocking reading idea from here .

Using labels to display text:

 import gtk import gobject import os from subprocess import Popen, PIPE import fcntl wnd = gtk.Window() wnd.set_default_size(400, 400) wnd.connect("destroy", gtk.main_quit) label = gtk.Label() label.set_alignment(0, 0) wnd.add(label) wnd.show_all() sub_proc = Popen("ping -c 10 localhost", stdout=PIPE, shell=True) sub_outp = "" def non_block_read(output): ''' even in a thread, a normal read with block until the buffer is full ''' fd = output.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) try: return output.read() except: return '' def update_terminal(): label.set_text(label.get_text() + non_block_read(sub_proc.stdout)) return sub_proc.poll() is None gobject.timeout_add(100, update_terminal) gtk.main() 
+9
source

You can use the subprocess module and the os module to return terminal output. You can check this question .

0
source

I tried to do this and really struggled. I could not get the first example to work and quickly switched to the second.

Using the 2nd example above (using a label to display the text) and found that this works well with Python 2.7, but I'm trying to use Python3, and some things just don't work.

I struggled for ages trying to upgrade to Python3, and I had to change some import operations and change gtk to Gtk, which made it work mostly, but I was really puzzled that Python3 used utf-8 codes. I finally started working by changing the "non_block_read" function, changing the returned text from utf-8 to a string, and dealing with the returned None register.

Hope this helps.

For completeness, I enclose my working code: -

 #!/usr/bin/env python3 import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk from gi.repository import GObject import os from subprocess import Popen, PIPE import fcntl wnd = Gtk.Window() wnd.set_default_size(400, 400) wnd.connect("destroy", Gtk.main_quit) label = Gtk.Label() label.set_alignment(0, 0) wnd.add(label) wnd.show_all() sub_proc = Popen("ping -c 10 localhost", stdout=PIPE, shell=True) sub_outp = "" def non_block_read(output): ''' even in a thread, a normal read with block until the buffer is full ''' fd = output.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) op = output.read() if op == None: return '' return op.decode('utf-8') def update_terminal(): label.set_text(label.get_text() + non_block_read(sub_proc.stdout)) return sub_proc.poll() is None GObject.timeout_add(100, update_terminal) Gtk.main() 
0
source

Source: https://habr.com/ru/post/1485563/


All Articles