我正在开发一个软件,我需要一个窗口,它将显示终端抛出的输出(就像包管理器一样)。例如,如果我给出安装命令,安装过程应该超出我的窗口而不是终端。有没有办法在python Gtk中执行此操作?
答案 0 :(得分:9)
如果您使用的是Linux(正如您所说),那么这样的事情应该有效:
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().decode("utf-8")
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()
非阻塞阅读理念来自here。
使用标签显示文字:
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().decode("utf-8")
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()
答案 1 :(得分:0)
您可以使用子进程模块和os模块取回终端输出。您可以查看question。
答案 2 :(得分:0)
我一直在努力做到这一点,而且确实很挣扎。 我无法使第一个示例正常工作,并迅速移至第二个示例。
使用上面的第二个示例(使用Label显示文本),发现这在Python 2.7上可以正常工作,但是我试图使用Python3,但有些事情不起作用。
我为尝试转换为Python3而苦苦挣扎了很长时间,不得不更改一些导入并将gtk更改为Gtk,这使其大部分都能正常工作,但真正令我难过的是由于Python3使用utf-8代码。 通过修改“ non_block_read”函数,将返回的文本从utf-8更改为字符串,并处理了返回None的情况,终于使它起作用了。
我希望这会有所帮助。
为完整起见,我附上我的工作代码:-
#!/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()