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与运行主循环,而你正在等待要下载的文件,你不会有使用线程。

+0

工作正是我想要它,辉煌的小动作。这肯定会在稍后派上用场。非常感谢! – Dustin

+0

+1简单而整齐! –

您将需要使用线程这一点。如果在回调函数中下载,则按钮&上的事件被阻止,您可以看到该按钮处于按下状态,即它正在等待回调函数完成并返回。

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:添加线程安全&也许禁用按钮,直到下载完成?