无法理解如何手动(我不在此阶段使用超时)刷新一个窗口,或者在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()
我现在越来越了解发生了什么;我只是慢慢拿起概念。
答案 0 :(得分:0)
那是因为在processlisting
中每次都会创建一个新标签,但是你永远不会将它添加到小部件树中,因此它永远不会显示。您应该做的是重用已在用户界面中添加的标签,并修改该标签。当您连接到刷新按钮的clicked
信号时,只需将其作为参数传递。
此外,无需在每个小部件上调用show
,只需在顶级gtk窗口上调用show_all
。
最后,您只需要连接到destroy
信号即可拨打gtk_main_quit
。 delete-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()”解决了这个问题。