Can kivy load dynamically images from urls?

866 views
Skip to first unread message

rmpython code

unread,
Feb 16, 2022, 7:43:35 PM2/16/22
to Kivy users support
Hello to everyone. This is my first post here.


I am trying to load as a icon widget the images from a news website.
I already got working the topic list view of the news. Now i am trying to add next to the news topia a picture from de api but i am had no success.

I was able to load an static image.png to all news topics bunt what i whish was to load a small picture from the "urlToImage" in the place of the static one.

I tryed to add a dynamic link to a detailed page with the full news but i had no success as well.

Does anyone knows if it is possible to have a list view and a detail view like in django/python. All with dynamic content?

thank you verry much.


This is what i did to get the news list:

######## main.py ###########

from kivy.app import App
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty
from kivymd.uix.list import MDList
from kivymd.uix.list import OneLineListItem
from kivymd.theming import ThemableBehavior
from kivymd.uix.list import ThreeLineAvatarListItem


import webbrowser
import requests


class ListItemWithIcon(ThreeLineAvatarListItem):
        source =StringProperty('string')



class ContentNavigationDrawer(BoxLayout):
        pass

class HomeScreen(Screen):
        pass

class DetailScreen(Screen):
        pass

class AboutScreen(Screen):
        pass


class MainWidget(BoxLayout):
        pass



class Mainapp(MDApp):
        def build(self):
                return MainWidget()


        def on_start(self):
                home_list = self.root.ids.home_list
                response = requests.get('https://newsapi.org/v2/top-headlines?country=br&category=business&apiKey=YOURAPIKEY')
                jasonresponse = response.json()
                #array
                articles = jasonresponse['articles']

                for article in articles:
                        title = article['title']
                        publishedAt = article['publishedAt']
                        news_source = article['source']['name']
                        publishedAtnews_source = publishedAt + ' - ' + news_source
                        urlToImage = article['urlToImage']
                        url = article['url']
                       
                        item = ListItemWithIcon(text=title,secondary_text=url,
                                                                        tertiary_text=publishedAtnews_source,
                                                                        source='image.png')
                        home_list.add_widget(item)


Mainapp().run()

####################

########## This is the main.vk 

<ListItemWithIcon>:

        ImageLeftWidget:
                MDChip:
                        text: 'url'
                        icon: root.source
                        on_release: root.buttonurl()


<ContentNavigationDrawer>:
        orientation: 'vertical'
        padding: 8
        spacing: 8

        AnchorLayout:
                anchor_x: 'left'
                size_hint: (None, None)
                height: avatar.height

                Image:
                        id: avatar
                        size_hint: (None, None)
                        size: "50dp", "50dp"
                        source: 'data/logo.png'




        MDLabel:
                text: 'rm News'
                font_style: "Button"
                size_hint: (None, None)
                height: self.texture_size[1]

        MDLabel:
                text: 'newsapp'
                font_style: "Caption"
                size_hint: (.5, None)
                height: self.texture_size[1]

        ScrollView:

                MDList:

                        OneLineIconListItem:
                                text: 'Início'
                                on_press:
                                        root.nav_drawer.set_state('close')
                                        root.screen_manager.current = 'home screen'


                        OneLineIconListItem:
                                text: 'Sobre rmcode'
                                on_press:
                                        root.nav_drawer.set_state('close')
                                        root.screen_manager.current = 'about screen'



<MainWidget>:
        Screen:


                MDNavigationLayout:
                        ScreenManager:
                                id: screen_manager

                                HomeScreen:
                                        name: 'home screen'
                                        BoxLayout:
                                                orientation: 'vertical'

                                                MDToolbar:
                                                        title: 'Notícias'
                                                        elevation: 10
                                                        left_action_items:[['menu', lambda x:nav_drawer.set_state("open")]]

                                                ScrollView:
                                                        MDList:
                                                                id: home_list



                                DetailScreen:
                                        name: 'detail screen'
                                        BoxLayout:
                                                orientation: 'vertical'

                                                MDToolbar:
                                                        title: 'Detalhe das Notícias'
                                                        elevation: 10
                                                        left_action_items:[['menu', lambda x:nav_drawer.set_state("open")]]

                                                ScrollView:
                                                        MDList:
                                                                id: detail




                                AboutScreen:
                                        name: 'about screen'
                                        BoxLayout:
                                                orientation: 'vertical'

                                                MDToolbar:
                                                        title: 'Sobre rmcode'
                                                        elevation: 10
                                                        left_action_items:[['menu', lambda x:nav_drawer.set_state("open")]]

                                                ScrollView:
                                                        MDLabel:
                                                                id: about_label
                                                                text_size: cm(6), cm(4)
                                                                size: self.texture_size
                                                                font_style: 'H4'
                                                                text_vcolor: (1,0,1,0)
                                                                halign: 'center'


                        MDNavigationDrawer:
                                id: nav_drawer

                                ContentNavigationDrawer:
                                        id: content_drawer
                                        screen_manager: screen_manager
                                        nav_drawer: nav_drawer



Elliot Garbus

unread,
Feb 16, 2022, 8:02:54 PM2/16/22
to kivy-...@googlegroups.com

If you are going to display an image from a URL I recommend using the AsyncImage widget.  You can pass the url as the source.

Rather that requests library, use kivy url request module.  https://kivy.org/doc/master/api-kivy.network.urlrequest.html?highlight=url#module-kivy.network.urlrequest

 

The requests library is blocking, the kivy URLrequest calls are non-blocking and integrated into kivy event loop.

Here are two examples, one that uses the URLRequest module, the other uses the AsyncImage Widget.

 

# Example using URLRequests

from kivy.app import App
from kivy.lang import Builder
from kivy.event import EventDispatcher
from kivy.network.urlrequest import UrlRequest
from kivy.properties import ListProperty
from kivy.clock import Clock

kv =
"""
BoxLayout:
    orientation: 'vertical'
    Label:
        id: label
        text_size: self.size
        valign: 'center'
        halign: 'center'
        padding: 10,10
        font_size: 40
    Button:
        size_hint_y: None
        height: 48
        text: 'Get Cat Facts'
        on_release: app.aw.check_net()
"""


class AccessWeb(EventDispatcher):
    facts = ListProperty()

   
def check_net(self):
        UrlRequest(
'https://cat-fact.herokuapp.com/facts', on_success=self.net_success, on_failure=self.net_fail)

   
def net_success(self,req, r):
       
print(f'Success: {req.is_finished}')
       
self.facts.clear()
       
for fact in r:
           
self.facts.append(fact['text'])
       
print(self.facts)
        app = App.get_running_app()
        app.root.ids.label.text =
self.facts[0]

   
def net_fail(self, req, r):
       
print("Fail:", r)


class TestAccessWebApp(App):

   
def __init__(self, **kwargs):
       
super().__init__(**kwargs)
       
self.cnt = 0
       
self.aw = None

    def
build(self):
        
self.aw = AccessWeb()
       
return Builder.load_string(kv)

   
def on_start(self):
        Clock.schedule_interval(
self.display_cat_fact, 5)

   
def display_cat_fact(self, dt):
       
if self.aw.facts:
           
self.root.ids.label.text = self.aw.facts[self.cnt]
           
self.cnt = (self.cnt+ 1) % len(self.aw.facts)


TestAccessWebApp().run()

 

# Example using AsyncImage

 

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.properties import StringProperty

kv =
"""
<ReadWriteScreen>:
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: root.movie_title
            size_hint_y: None
            height: 48
            font_size: 24
        AsyncImage:
            source: root.source
        Button:
            text: 'Go Back'
            size_hint_y: None
            height: 48
            on_release: root.manager.current = 'title'

<TitleScreen@Screen>:
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: 'Home Screen'
        Button:
            text: 'Go to Movie'
            size_hint_y: None
            height: 48
            on_release: root.manager.current = 'movie'
ScreenManager:
    TitleScreen:
        name: 'title'
    ReadWriteScreen:
        name: 'movie'           

"""

class ReadWriteScreen(Screen):
    movie_title = StringProperty()
    source = StringProperty()

   
def on_pre_enter(self, *args):
       
self.movie_title = 'Interstellar'
       
self.source = 'https://m.media-amazon.com/images/M/MV5BZjdkOTU3MDktN2IxOS00OGEyLWFmMjktY2FiMmZkNWIyODZiXkEyXkFqcGdeQXVyMTMxODk2OTU@.jpg'


class MovieApp(App):
   
def build(self):
       
return Builder.load_string(kv)

MovieApp().run()

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/932ff16b-d722-4326-823b-5588443f884an%40googlegroups.com.

 

rmpython code

unread,
Feb 28, 2022, 4:30:29 PM2/28/22
to Kivy users support
Thank you very much ElliotG.
It did work!

Reply all
Reply to author
Forward
0 new messages