@ wrote... (10 months ago)

I really want to like Kivy

I was trying to asyncronously load comic book images out of a cbr file (a rar archive) but was having a hell of a time figuring it out.

Like most things in Kivyland, it wasn't hard after you already know how. The key is providing a load_callback and then bind.

The docs almost tell you everything you need to know, except they don't say shit about load_callback, you need to spelunk through the source code (look in _load()) to figure that out.

And then some trial and error to figure out you need to return a kivy.core.image.Image and not a kivy.uix.image.Image because that wouldn't have saved me a ½ inch of hairline…

The following is paraphrased from my program so it probably won't work exactly as I've typed it here. It's too much work to make full working example. You're welcome.

#:import Page myapp.kvwidgets.Page

<Page>:
    orientation: "vertical"
    size_hint: None, None
    size: 300, 300

    canvas.before:
        Color:
            rgba: 0,0,0,1
        Rectangle:
            pos: self.pos
            size: self.size

    ImageButton:
        id: image
from kivy.logger import Logger
from kivy.core.image import Image as CoreImage
from kivy.uix.boxlayout import BoxLayout
from kivy.loader import Loader
from io import BytesIO


def rar_loader(self, rarfile, filename):
    Logger.debug("rar_loader('%s')", filename)

    _, ext = os.path.splitext( filename )
    ext = ext[1:].lower()

    data = rarfile.open(filename).read()
    data = BytesIO(data)

    return CoreImage(data, ext=ext, filename=filename)


class Page(BoxLayout):
    def __init__(self, rarfile, filename, **kw):
        """
        rarfile is a RarFile() object
        filename is the path inside the rarfile
        """
        super(Page, self).__init__(**kw)

        def cb_loaded(proxy_image):
            # called when image is finished being loaded
            self.ids.image.texture = proxy_image.image.texture

        try:
            loader_func = functools.partial(rar_loader, rarfile)

            proxy_image = Loader.image(filename, load_callback=loader_func)
            proxy_image.bind(on_load=cb_loaded)

            # show loading image
            self.ids.image.texture = proxy_image.texture
        except Exception as e:
            Logger.error( str(e) )
Category: tech, Tags: kivy
Comments: 0
Click here to add a comment