Python/Glade/PyGTK - 下载Glade标签中的百分比
问题描述:
我正在尝试使用Glade,PyGTK和Python设置一个小小的下载应用程序。我已经计划过如何编写这个进度条和所有的脚本,但我觉得我正在以错误的方式去做......呃...它不工作。Python/Glade/PyGTK - 下载Glade标签中的百分比
我正在使用我发现的一个小脚本来检查下载的百分比,然后通常会打印到终端,但是我希望它改变了Glade中的标签。尽管在下载过程中标签不会改变,但GUI会冻结,直到文件完成,然后更新说明它已完成100%。
什么是最好的方法来做这样的工作?任何帮助表示感谢,提前致谢!
的Python脚本:
import sys
import pygtk
pygtk.require("2.0")
import gtk
import gtk.glade
import urllib2
import time
class FileSelector:
def __init__(self):
#Set the Glade file
filename = "FileSelector.glade"
self.builder = gtk.Builder()
self.builder.add_from_file(filename)
self.builder.connect_signals(self)
self.window = self.builder.get_object("MainWindow")
self.label1 = self.builder.get_object("label1")
def on_MainWindow_destroy(self, obj):
gtk.main_quit() #make the program quit
def btnSubmit_clicked(self, widget):
status_dropbox = self.builder.get_object("chkboxDropbox")
status_python = self.builder.get_object("chkboxPython")
status_chrome = self.builder.get_object("chkboxChrome")
#Start downloader script
url = "http://dl.dropbox.com/u/9235267/project.png"
file_name = url.split('/')[-1]
u = urllib2.urlopen(url)
f = open(file_name, 'wb')
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
print "Downloading: %s Bytes: %s" % (file_name, file_size)
file_size_dl = 0
block_sz = 8192
while True:
buffer = u.read(block_sz)
if not buffer:
break
file_size_dl += len(buffer)
f.write(buffer)
status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100./file_size)
self.label1.set_text(status)
f.close()
if __name__ == "__main__":
FileSelector()
gtk.main()
格莱德文件(FileSelector.glade):
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="MainWindow">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">MainWindow</property>
<property name="resizable">False</property>
<property name="window_position">center</property>
<signal name="destroy" handler="on_MainWindow_destroy" swapped="no"/>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Enviroment Downloader</property>
<attributes>
<attribute name="style" value="normal"/>
<attribute name="size" value="300"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="chkboxDropbox">
<property name="label" translatable="yes">Dropbox</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="chkboxPython">
<property name="label" translatable="yes">Python</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="chkboxChrome">
<property name="label" translatable="yes">Google Chrome</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btnSubmit">
<property name="label" translatable="yes">Download/Run</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="btnSubmit_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
答
行后
self.label1.set_text(status)
地址:
while gtk.events_pending():
gtk.main_iteration()
这将更新GUI与运行主循环,而你正在等待要下载的文件,你不会有使用线程。
答
您将需要使用线程这一点。如果在回调函数中下载,则按钮&上的事件被阻止,您可以看到该按钮处于按下状态,即它正在等待回调函数完成并返回。
import sys
import pygtk
pygtk.require("2.0")
import gtk
import gtk.glade
import urllib2
import time
import threading
import glib
# Replace this with what you want to do
def download(label):
index = 0
while True:
if index>1200:
break
index += 120
time.sleep(1)
status = r"%10d " % (index)
label.set_label(status)
class FileSelector:
def __init__(self):
#Set the Glade file
filename = "FileSelector.glade"
self.builder = gtk.Builder()
self.builder.add_from_file(filename)
self.builder.connect_signals(self)
self.window = self.builder.get_object("MainWindow")
self.label1 = self.builder.get_object("label1")
def on_MainWindow_destroy(self, obj):
gtk.main_quit() #make the program quit
def btnSubmit_clicked(self, widget):
status_dropbox = self.builder.get_object("chkboxDropbox")
status_python = self.builder.get_object("chkboxPython")
status_chrome = self.builder.get_object("chkboxChrome")
# Launch the thread to update label
threading.Thread(target=download, args=(self.builder.get_object("label1"),)).start()
if __name__ == "__main__":
FileSelector()
glib.threads_init()
# Add gdk thread enter and leave
gtk.main()
你可以参考this question还有:虽然我的Python的知识是零,我可以使用谷歌等如下煮了一些样品。
希望这有助于!
PS:添加线程安全&也许禁用按钮,直到下载完成?
工作正是我想要它,辉煌的小动作。这肯定会在稍后派上用场。非常感谢! – Dustin
+1简单而整齐! –