简体   繁体   English

Python / Glade / PyGTK - 下载Glade标签中的百分比

[英]Python/Glade/PyGTK - Download Percentage in Glade Label

I'm trying to setup a little download application using Glade, PyGTK, and Python. 我正在尝试使用Glade,PyGTK和Python设置一个小型下载应用程序。 I have it planned how I'd like to script this progress bar and all, though I feel I'm going about it the wrong way as... Well... It's not working. 我已经计划好了如何编写这个进度条和所有内容的脚本,尽管我觉得我的方式错误,因为......好吧......它没有用。

I'm using a little script I found for a checking the percentage of a download and then usually it would print to terminal, but instead I'd like it alter a label in Glade. 我正在使用我找到的一个小脚本来检查下载的百分比,然后通常它会打印到终端,但我想它会改变Glade中的标签。 Though, instead of the label changing when as the download progresses, the GUI freezes until the file is done and THEN updates saying it's 100% complete. 虽然在下载过程中不会改变标签,但GUI会冻结,直到文件完成,然后更新说它已完成100%。

What would be the best method about making something like this work? 制作像这样的作品最好的方法是什么? Any help is appreciated, thanks in advance! 任何帮助表示赞赏,提前谢谢!

Python Script: 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()

Glade File (FileSelector.glade): Glade文件(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>

After the line 行后

self.label1.set_text(status)

Add: 加:

while gtk.events_pending():
    gtk.main_iteration()

This will update the GUI and run the main loop while you are waiting for the file to download, and you won't have to use threads. 这将在您等待文件下载时更新GUI并运行主循环,您不必使用线程。

You will need to use threads for this. 您需要使用线程。 If you are downloading in the callback function then the eventing is blocked on the button & you can see that the button is in pressed state ie it is waiting for the callback function to complete and return. 如果您在回调函数中下载,则按钮上的事件被阻止,您可以看到按钮处于按下状态,即它正在等待回调函数完成并返回。 Although my knowledge of python is nil, I could cook up some sample as follows using google etc: 虽然我对python的了解是零,但我可以使用谷歌等制作一些样本如下:

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()

You can refer this question as well. 你也可以参考这个问题
Hope this helps! 希望这可以帮助!
PS: Add thread safety & maybe disable button till download is complete? PS:添加线程安全并可能禁用按钮直到下载完成?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM