【问题标题】:Show terminal output in a gui window using python Gtk使用 python Gtk 在 gui 窗口中显示终端输出
【发布时间】:2013-06-06 22:42:09
【问题描述】:

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

我使用的是 Ubuntu 13.04。

【问题讨论】:

标签: python gtk


【解决方案1】:

如果你在 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()

【讨论】:

  • 这会将其更新为文本视图。如果我想将它发送到标签怎么办?
  • 因为 textview 看起来有些难看
  • 那种。但我想要的实际输出是,就像突触包管理器中发生的那样。通过它安装时显示的输出
  • 据我所知,突触在 ScrolledWindow 中使用 TextView 和 Expander 来显示/隐藏它。此外,使用了固定宽度的字体。我相应地更新了第一个示例。当然,您可以进一步细化字体和显示样式以满足您的需求。
【解决方案2】:

我一直在努力做到这一点并且真的很挣扎。 我无法让第一个示例正常工作,并迅速转移到第二个示例。

使用上面的第二个示例(使用标签显示文本),发现这适用于 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()

【讨论】:

    【解决方案3】:

    您可以使用 subprocess 模块和 os 模块来取回终端输出。您可以查看此question

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-16
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2023-02-03
      • 2021-11-30
      • 2019-04-22
      相关资源
      最近更新 更多