使用python G gui窗口显示终端输出

2024-04-20 01:58:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个软件,我想要一个窗口,显示终端抛出的输出(就像包管理器那样)。例如,如果我发出install命令,安装过程应该输出到我的窗口,而不是终端。在python Gtk中有这样做的方法吗?


Tags: install方法命令终端gtk管理器软件过程
3条回答

您可以使用子流程模块和操作系统模块来获取终端输出。您可以检查这个question

我一直在努力做到这一点,真的很挣扎。 我没法让第一个例子起作用,所以很快就转到了第二个。

使用上面的第二个例子(使用Label来显示文本),发现这对Python 2.7很好,但是我试图使用Python3,有些事情就是不起作用。

我挣扎了好几年试图转换为Python3,不得不改变一些进口产品,并将gtk改为gtk,这使它大部分工作,但真正困扰我的是Python3使用utf-8代码。 最后,我修改了“non_block_read”函数,将返回的文本从utf-8改为string,并处理了return 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()

如果您使用的是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()

相关问题 更多 >