1

I am trying to build an app that downloads a file, whose progress can be tracked on a kivy app.

I have looked at the example here and here for the download progress. This is my code:

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.popup import Popup
from kivy.factory import Factory
from kivy.properties import ObjectProperty
from kivy.clock import Clock
import urllib

URL = "http://s9.videozoo.me/S/saenai_heroine_no_sodatekata_flat_-_11.mp4?st=Ow7pwXbRt6vPWE-kr5Sn1A&e=1498847899&start=0"

class PopupBox(Popup):
    pop_up_text = ObjectProperty()

    def update_pop_up_text(self, p_message):
        self.pop_up_text.text = p_message


class MyApp(App):
    # layout
    def show_popup(self):
        self.pop_up = Factory.PopupBox()
        self.pop_up.update_pop_up_text('Running some task...')
        self.pop_up.open()

    def build(self):
        layout = BoxLayout(padding=10, orientation='vertical')
        btn1 = Button(text="OK")
        btn1.bind(on_press=self.buttonClicked)
        layout.add_widget(btn1)
        self.lbl1 = Label(text="test")
        layout.add_widget(self.lbl1)
        self.txt1 = TextInput(text='', multiline=False)
        layout.add_widget(self.txt1)
        return layout

    # button click function
    def buttonClicked(self, btn):
        self.lbl1.text = "You wrote " + self.txt1.text
        self.show_popup()

        self.download_file(URL)
        self.pop_up.dismiss()

    def download_file(self, url):
        u = urllib.request.urlopen(url)
        meta = u.info()
        metaInfo = str(meta).split()
        fileTotalbytes = int(metaInfo[46])

        data_blocks = []
        total = 0

        while True:
            block = u.read(1024)
            data_blocks.append(block)
            total += len(block)
            hash = ((60 * total) // fileTotalbytes)
            print("[{}{}] {}%".format('#' * hash, ' ' * (60 - hash), int(total / fileTotalbytes * 100)), end="\r")

            if not len(block):
                break
            data = b''.join(data_blocks)  # had to add b because I was joining bytes not strings
        u.close()

# run app
if __name__ == "__main__":
    MyApp().run()

However, I am confused as to how do I bind the download_file function with the kivy widget functionality so as to make it work. How do I appropriately modify the print function so as to make it work with the widget

Echchama Nayak
  • 971
  • 3
  • 23
  • 44

1 Answers1

0

If you block in the mainthread kivy can no longer update the GUI. Instead create a new thread and use the @mainthread annotation to do gui updates.

Instead of the print you have to manipulate kivy widgets. You could create a rectangle and increase the width to 100%. You could create a textinput and output your text there.

syntonym
  • 7,134
  • 2
  • 32
  • 45