显示内容然后在PyGTK中手动刷新(2)

时间:2017-10-23 10:45:20

标签: python gtk pygtk gtk2

无法理解如何手动(我不在此阶段使用超时)刷新一个窗口,或者在PyGTK版本2中的一部分窗口。

我想显示一些信息,在这个例子中,选择来自" df"命令,然后能够使用"刷新"手动刷新窗口。按钮。我已经查看了各种示例和PyGTK教程,但确切的放置代码的地方让我感到惊讶。在" freedisk"中使用queue_draw尝试函数,在其中的另一个函数中,在" main"循环,没有成功。

我很欣赏GTK3是目前的首选版本,但在更新之前,我宁愿做到这一点。

" freedisk"的代码:

#!/usr/bin/env python

import pango, pygtk, subprocess, re, string, decimal, time
pygtk.require('2.0')
import gtk

def yield_lines(data):
    for line in data.split("\n"):
        yield line

def line_to_list(line):
    return re.sub(" +", " ", line).split()

def remov_percent(col):
    return re.sub("%", "", col)


class freedisk:
    def getdiskfree(self):
        diskfreecmd = ['/usr/bin/df', '-hlT', '-x', 'tmpfs']
        diskfree = subprocess.Popen(diskfreecmd, stdout=subprocess.PIPE).communicate()[0]
        return diskfree

    def delete_event(self, widget, event, data=None):
        gtk.main_quit()
        return False

    def destroy(self, widget, data=None):
        gtk.main_quit()

    def __init__(self):
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.connect("delete_event", self.delete_event)

        box1 = gtk.VBox(False, 10)
        box1a = gtk.HBox(False, 0)
        box2 = gtk.VBox(False, 10)
        box3 = gtk.HBox(False, 0)

        frame_1 = gtk.Frame()

        window.add(box1)

        diskfreedata = self.getdiskfree()
        diskfreedata = diskfreedata.replace("Mounted on", "Mounted_on")

        lines = yield_lines(diskfreedata)

        headers = line_to_list(lines.next())

        columns = [list() for i in range(len(headers))]

        for i,h in enumerate(headers):
            columns[i].append(h)

        for line in lines:
            for i,l in enumerate(line_to_list(line)):
                columns[i].append(l)

        j=0
        for i in columns[0]:
            j += 1

        title = gtk.Label('Disk usage and free space')
        box1.pack_start(title, False, False, 10)
        box1.pack_start(box1a, True, True, 0)
        box1a.pack_start(frame_1, True, True, 20)
        frame_1.add(box2)

        ucdiskfreedata = unicode(diskfreedata)

        label = gtk.Label(diskfreedata)
        label.set_line_wrap(False)
        label.set_max_width_chars(80)
        label.modify_font(pango.FontDescription("monospace"))

        box_sp1 = gtk.HBox(False, 0)
        box_sp2 = gtk.HBox(False, 0)

        refresh_button = gtk.Button("Refresh")

        close_button = gtk.Button("Close")
        close_button.connect("clicked", self.delete_event, "quit")

        mntlabel = [list() for i in range(j)]
        sizelabel = [list() for i in range(j)]
        progbar = [list() for i in range(j)]
        freelabel = [list() for i in range(j)]
        perlabel = [list() for i in range(j)]

        rows = [list() for i in range(j)]

        box2.pack_start(box_sp1, False, False, 0)

        rows[0] = gtk.HBox(True, 0)
        box2.pack_start(rows[0], False, False, 5)

        mntlabel[0] = gtk.Label(columns[6][0])
        freelabel[0] = gtk.Label(columns[4][0])
        sizelabel[0] = gtk.Label(columns[2][0])
        blank = gtk.Label(columns[5][0])
        rows[0].pack_start(mntlabel[0], False, False, 0)
        rows[0].pack_start(sizelabel[0], False, False, 0)
        rows[0].pack_start(blank, False, False, 0)
        rows[0].pack_start(freelabel[0], False, False, 0)

        for i in range(1,j):
            x = remov_percent(columns[5][i])
            y = decimal.Decimal(x) /  decimal.Decimal('100') 
            mntlabel[i] = gtk.Label(columns[6][i])
            mntlabel[i].set_justify(gtk.JUSTIFY_RIGHT)
            freelabel[i] = gtk.Label(columns[4][i])
            sizelabel[i] = gtk.Label(columns[2][i])
            progbar[i] = gtk.ProgressBar()
            gtk.ProgressBar.set_fraction(progbar[i], y)
            progbar[i].set_text(str(columns[5][i]))
            rows[i] = gtk.HBox(True, 0)
            rows[i].pack_start(mntlabel[i], False, False, 0)
            rows[i].pack_start(sizelabel[i], False, False, 0)
            rows[i].pack_start(progbar[i], False, False, 0)
            rows[i].pack_start(freelabel[i], False, False, 0)
            box2.pack_start(rows[i], False, False, 0)

            box2.pack_start(box_sp2, False, False, 10)

            box3.pack_end(close_button, False, False, 20)
            box3.pack_end(refresh_button, False, False, 20)
            box1.pack_start(box3, False, False, 10)

            box1.show()
            box1a.show()
            box2.show()
            box_sp1.show()
            box_sp2.show()
            frame_1.show()
            title.show()

            mntlabel[0].show()
            blank.show()
            for i in range(0, j):
               rows[i].show()
               mntlabel[i].show()
               sizelabel[i].show()
               freelabel[i].show()
            for i in range(1,j):
                progbar[i].show()

            refresh_button.show()
            close_button.show()
            box3.show()
            window.show()


def main():
    gtk.main()

if __name__ == "__main__":
    freedisk()
    main()

编辑(24.10.17)然后添加一个更简单的例子,只显示命令的输出" ls":

#!/usr/bin/env python

import pango, pygtk, subprocess, re, string, decimal, time
pygtk.require('2.0')
import gtk


class PyGlist:

    def getlisting(self):
        listingcmd = ['ls', '-1']
        listing = subprocess.Popen(listingcmd, stdout=subprocess.PIPE).communicate()[0]
        return listing

    def delete_event(self, widget, event, data=None):
        gtk.main_quit()
        return False

    def destroy(self, widget, data=None):
        gtk.main_quit()

    def __init__(self):
        # nothing here
        return None

    def processlisting(self):
        listingdata = self.getlisting()
        print (listingdata)
        loclabel = gtk.Label(listingdata)
        loclabel.set_line_wrap(False)
        loclabel.set_max_width_chars(80)
        loclabel.modify_font(pango.FontDescription("monospace"))
        return loclabel

    def refresh(self, widget, data):
        widget = self.processlisting()
        widget.queue_draw()
        return 

    def main(self):
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.connect("delete_event", self.delete_event)

        box1 = gtk.VBox(False, 10)
        box1a = gtk.HBox(False, 0)
        box2 = gtk.VBox(False, 10)
        box3 = gtk.HBox(False, 0)
        frame_1 = gtk.Frame()
        window.add(box1)

        title = gtk.Label('Listing')
        box1.pack_start(title, False, False, 10)
        box1.pack_start(box1a, True, True, 0)
        box1a.pack_start(frame_1, True, True, 20)
        frame_1.add(box2)

        label = self.processlisting()

        box_sp1 = gtk.HBox(False, 0)
        box_sp2 = gtk.HBox(False, 0)

        box2.pack_start(label, False, False, 0)

        refresh_button = gtk.Button("Refresh")
        refresh_button.connect("clicked", self.refresh, label)

        close_button = gtk.Button("Close")
        close_button.connect("clicked", self.delete_event, "quit")

        box3.pack_end(close_button, False, False, 20)
        box3.pack_end(refresh_button, False, False, 20)
        box1.pack_start(box3, False, False, 10)

        box1.show()
        box1a.show()
        label.show()
        box2.show()
        box_sp1.show()
        box_sp2.show()
        frame_1.show()
        title.show()

        refresh_button.show()
        close_button.show()
        box3.show()
        window.show()

        gtk.main()


if __name__ == "__main__":
    pyglist =PyGlist()
    pyglist.main()

我现在越来越了解发生了什么;我只是慢慢拿起概念。

2 个答案:

答案 0 :(得分:0)

那是因为在processlisting中每次都会创建一个新标签,但是你永远不会将它添加到小部件树中,因此它永远不会显示。您应该做的是重用已在用户界面中添加的标签,并修改该标签。当您连接到刷新按钮的clicked信号时,只需将其作为参数传递。

此外,无需在每个小部件上调用show,只需在顶级gtk窗口上调用show_all

最后,您只需要连接到destroy信号即可拨打gtk_main_quitdelete-event是您想拦截想要关闭窗口并希望更改默认行为的用户。

#!/usr/bin/env python

import pango, pygtk, subprocess, re, string, decimal, time
pygtk.require('2.0')
import gtk


class PyGlist:

    def getlisting(self):
        listingcmd = ['ls', '-1']
        listing = subprocess.Popen(listingcmd, stdout=subprocess.PIPE).communicate()[0]
        print listing
        return listing

    def on_destroy(self, widget, data=None):
        gtk.main_quit()

    def refresh(self, refresh_button, label):
        label.set_text(self.getlisting())

    def main(self):
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.connect("destroy", self.on_destroy)

        box1 = gtk.VBox(False, 10)
        box1a = gtk.HBox(False, 0)
        box2 = gtk.VBox(False, 10)
        box3 = gtk.HBox(False, 0)
        frame_1 = gtk.Frame()
        window.add(box1)

        title = gtk.Label('Listing')
        box1.pack_start(title, False, False, 10)
        box1.pack_start(box1a, True, True, 0)
        box1a.pack_start(frame_1, True, True, 20)
        frame_1.add(box2)

        label = gtk.Label(self.getlisting())
        label.set_line_wrap(False)
        label.set_max_width_chars(80)
        label.modify_font(pango.FontDescription("monospace"))

        box_sp1 = gtk.HBox(False, 0)
        box_sp2 = gtk.HBox(False, 0)

        box2.pack_start(label, False, False, 0)

        refresh_button = gtk.Button("Refresh")
        refresh_button.connect("clicked", self.refresh, label)

        close_button = gtk.Button("Close")
        close_button.connect("clicked", self.on_destroy)

        box3.pack_end(close_button, False, False, 20)
        box3.pack_end(refresh_button, False, False, 20)
        box1.pack_start(box3, False, False, 10)

        window.show_all()

        gtk.main()


if __name__ == "__main__":
    pyglist =PyGlist()
    pyglist.main()

答案 1 :(得分:0)

我终于破解了它。感谢上面海报的帮助。

更简单的例子向我展示了我过度复杂的事情。

原始程序“freedisk”我终于开始工作,将更多代码移动到一个单独的函数中,这样可以更容易地看到发生了什么。

基本上,目的是获取“df”的输出并使用混合文本和图形显示稍微调整一下。

除了任何格式框,标题等之外,还会有一个VBox容器,每行“df”输出一个HBox,以文本形式重新创建一些柱状输出,但是有一列进度条。

数据转换和行的创建我移动到一个单独的函数中。

这将在最初调用,然后每次按下“刷新”按钮。

在重新计算数据然后重新输出之前,垂直框内的任何现有行都将被销毁。这就是拼图的最后一块落到了原点。

在摧毁小部件并更换它们之后,我没有意识到它们必须重新“显示”。添加最后一行“widget.show_all()”解决了这个问题。