Search code examples
pythonkivykivy-languagekivymd

Displaying data from API request in MDTab


Iam trying to learn coding with Python and iam making an application that tracks session times from users using KivyMD. At the moment iam trying to display the total amount of time by fetching json data trough an api call from my database. I wrote a function to fetch and process the json data to calculate the total time. The function must fire automatically to show the data (variable:total_minutes) in the MDLabel time_label when the Mijn sessie Tab loads. This is where iam getting very confused.

I found the on_pre_enter function in Kivy which fires the function when the screen loads but it only works in the Screen Class and not in the Tabs Class. I have no idea how i can use the python variable in the Tabs class if i do the python logic in the Screen class. I have tried many things with Objectproperty and Stringproperty but none where succesfull. I think iam missing something bigger here.

I will post the code to make things more clearly when you will see the application for yourself. For safety reasons i replaced the api request function with a small function which produces the same outcome (float).

Many thanks in advance!

main.py file

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.tab import MDTabsBase
from kivymd.font_definitions import fonts
from kivymd.icon_definitions import md_icons
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.widget import Widget
from kivymd.uix.label import MDLabel
import requests
import json
from datetime import datetime

Window.size = (300, 500) # voor develop doeleinden mobielscherm

class Screen1(Screen):
    pass

    def on_pre_enter(self, *args):

        def func(a, b):
            total_minutes = a - b
            return total_minutes

        print(func(3000,1500))

class Screen2(Screen):
    pass


class Screen3(Screen):
    pass


class Screen4(Screen):
    pass


class Tab_mijn_sessie(FloatLayout, MDTabsBase):
    pass


class Tab_alarm(FloatLayout, MDTabsBase):
    pass


class Tab_actieve_drinkers(FloatLayout, MDTabsBase):
    pass


class Tab_score(FloatLayout, MDTabsBase):
    pass


class Tab_achievments(FloatLayout, MDTabsBase):
    pass


class Tab_historie(FloatLayout, MDTabsBase):
    pass


class DemoApp(MDApp):

    def build(self):

        self.theme_cls.primary_palette = 'Red'
        self.theme_cls.theme_style = 'Dark'
        screen = Builder.load_file('demo_file.kv')

        return screen


DemoApp().run()

demo_file.kv file

Screen:

    NavigationLayout:

        ScreenManager:
            id:screen_manager

            Screen1:
                name: 'home_screen'

                BoxLayout:
                    name: 'home_layout'
                    orientation: 'vertical'

                    MDToolbar:
                        title: 'Huidige sessie'
                        left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]
                        specific_text_color: 1,1,1,1

                    MDTabs:
                        id:home_tabs
                        tab_bar_height: '35dp'
                        text_color_active: 1,1,0,1
                        text_color_normal: 0,0,0,1
                        color_indicator: 0.95, 0.95, 0.1, 1
                        tab_indicator_anim: True
                        anim_duration: 0.2
                        tab_indicator_height: '3dp'

                        Tab_mijn_sessie:
                            text: 'Mijn sessie'

                        Tab_alarm:
                            text: 'Alarm'

                        Tab_actieve_drinkers:
                            text: 'Actieve drinkers'

                    MDToolbar:
                        id: bottom_toolbar_scr1
                        name: 'bottom_toolbar'
                        specific_text_color: 1,1,1,1
                        title: '          Sessie inactief..'

            Screen2:
                name: 'statistieken_screen'

                BoxLayout:
                    name: 'statistieken_layout'
                    orientation: 'vertical'

                    MDToolbar:
                        title: 'Statistieken'
                        left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]
                        specific_text_color: 1,1,1,1

                    MDTabs:
                        id:home_tabs
                        tab_bar_height: '35dp'
                        text_color_active: 1,1,0,1
                        text_color_normal: 0,0,0,1
                        color_indicator: 0.95, 0.95, 0.1, 1
                        tab_indicator_anim: True
                        anim_duration: 0.2
                        tab_indicator_height: '3dp'

                        Tab_score:
                            text: 'Scorebord'

                        Tab_achievments:
                            text: 'Achievements'

                        Tab_historie:
                            text: 'Historie'

                    MDToolbar:
                        id: bottom_toolbar_scr2
                        name: 'bottom_toolbar'
                        specific_text_color: 1,1,1,1
                        title: '          Sessie inactief..'


            Screen3:
                name: 'logout_screen'

                BoxLayout:
                    name: 'logout_layout'
                    orientation: 'vertical'

                    MDToolbar:
                        title: 'Uitloggen'
                        left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]
                        specific_text_color: 1,1,1,1

                    Widget:


            Screen4:
                name: 'profile_screen'

                BoxLayout:
                    name: 'profile_layout'
                    orientation: 'vertical'

                    MDToolbar:
                        title: 'Profiel'
                        left_action_items: [['menu', lambda x: nav_drawer.set_state("open")]]
                        specific_text_color: 1,1,1,1

                    Widget:

                    MDToolbar:
                        id: bottom_toolbar_scr4
                        name: 'bottom_toolbar'
                        specific_text_color: 1,1,1,1
                        title: '          Sessie inactief..'

        MDNavigationDrawer:
            id:nav_drawer

            BoxLayout:
                orientation: 'vertical'
                spacing: '8dp'
                padding: '8dp'

                Image:
                    source: 'avatar.jpg'


                MDLabel:
                    text: '     Name'
                    front_style: 'Subtitle1'
                    size_hint_y: None
                    height: self.texture_size[1]

                MDLabel:

                    text: '     [email protected]'
                    front_style: 'Caption'
                    size_hint_y: None
                    height: self.texture_size[1]

                ScrollView:
                    MDList:

                        OneLineIconListItem:
                            theme_text_color: 'Custom'
                            text_color: 244/255, 67/255, 54/255, 1
                            text: 'Huidige sessie'


                            on_press:
                                screen_manager.current = 'home_screen'
                                nav_drawer.set_state("close")

                            IconLeftWidget:
                                theme_text_color: 'Custom'
                                text_color: 0.95, 0.95, 0.1, 1
                                icon: 'beer'
                                on_press:
                                    screen_manager.current = 'home_screen'
                                    nav_drawer.set_state("close")

                        OneLineIconListItem:
                            theme_text_color: 'Custom'
                            text_color: 244/255, 67/255, 54/255, 1
                            text: 'Statistieken'

                            on_press:
                                screen_manager.current = 'statistieken_screen'
                                nav_drawer.set_state("close")

                            IconLeftWidget:
                                icon: 'history'
                                theme_text_color: 'Custom'
                                text_color: 0.95, 0.95, 0.1, 1
                                on_press:
                                    screen_manager.current = 'historie_screen'
                                    nav_drawer.set_state("close")

                        OneLineIconListItem:
                            theme_text_color: 'Custom'
                            text_color: 244/255, 67/255, 54/255, 1
                            text: 'Profiel'

                            on_press:
                                screen_manager.current = 'profile_screen'
                                nav_drawer.set_state("close")

                            IconLeftWidget:
                                icon: 'face-profile'
                                theme_text_color: 'Custom'
                                text_color: 0.95, 0.95, 0.1, 1
                                on_press:
                                    screen_manager.current = 'profile_screen'
                                    nav_drawer.set_state("close")

                        OneLineIconListItem:
                            theme_text_color: 'Custom'
                            text_color: 244/255, 67/255, 54/255, 1
                            text: 'Uitloggen'
                            on_press:
                                screen_manager.current = 'logout_screen'
                                nav_drawer.set_state("close")

                            IconLeftWidget:

                                icon: 'logout'
                                theme_text_color: 'Custom'
                                text_color: 0.95, 0.95, 0.1, 1
                                on_press:
                                    screen_manager.current = 'logout_screen'
                                    nav_drawer.set_state("close")

<Tab_mijn_sessie>:

    MDLabel:
        text: 'Total time'
        font_style: 'H6'
        halign: 'center'
        pos_hint: {"center_x": .5, "center_y": .4}
    MDLabel:
        id : time_label
        text: '(this has to display the total amount of time)'
        font_style: 'Body2'
        halign: 'center'
        pos_hint: {"center_x": .5, "center_y": .3}

    MDFlatButton:
        theme_text_color: 'Custom'
        text_color: 1,1,1,1
        halign: 'center'
        text:'Activate session'
        user_font_size: "48sp"
        pos_hint: {"center_x": .5, "center_y": .7}
        on_press:
            app.root.ids.bottom_toolbar_scr1.title = '          Sessie actief!'
            app.root.ids.bottom_toolbar_scr1.specific_text_color = 0,1,0,1
            app.root.ids.bottom_toolbar_scr2.title = '          Sessie actief!'
            app.root.ids.bottom_toolbar_scr2.specific_text_color = 0,1,0,1
            app.root.ids.bottom_toolbar_scr4.title = '          Sessie actief!'
            app.root.ids.bottom_toolbar_scr4.specific_text_color = 0,1,0,1


<Tab_alarm>:
    MDLabel:
        halign: 'center'
        text:'Alarm'
        user_font_size: "48sp"
        pos_hint: {"center_x": .5, "center_y": .5}


<Tab_actieve_drinkers>:
    MDLabel:
        halign: 'center'
        text:'Actieve drinkers'
        user_font_size: "48sp"
        pos_hint: {"center_x": .5, "center_y": .5}

<Tab_score>:
    MDLabel:
        halign: 'center'
        text:'Scorebord'
        user_font_size: "48sp"
        pos_hint: {"center_x": .5, "center_y": .5}

<Tab_achievments>:
    MDLabel:
        halign: 'center'
        text:'Achievments'
        user_font_size: "48sp"
        pos_hint: {"center_x": .5, "center_y": .5}

<Tab_historie>:
    FloatLayout:
        MDLabel:
            halign: 'center'
            text:'Historie'
            user_font_size: "48sp"
            pos_hint: {"center_x": .5, "center_y": .5}

        MDFlatButton:
            id: flat
            text: 'druk hier'
            pos_hint: {"center_x": .5, "center_y": 0.4}


Solution

  • from kivy.lang import Builder
    from kivy.uix.floatlayout import FloatLayout
    
    from kivymd.app import MDApp
    from kivymd.uix.tab import MDTabsBase
    from kivymd.icon_definitions import md_icons
    
    KV = '''
    BoxLayout:
        orientation: "vertical"
    
        MDToolbar:
            title: "Example Tabs"
    
        MDTabs:
            id: tabs
            on_tab_switch: app.on_tab_switch(*args)
    
    
    <Tab>:
    
        MDIconButton:
            id: icon
            icon: app.icons[0]
            user_font_size: "48sp"
            pos_hint: {"center_x": .5, "center_y": .5}
    '''
    
    
    class Tab(FloatLayout, MDTabsBase):
        '''Class implementing content for a tab.'''
    
    
    class Example(MDApp):
        icons = list(md_icons.keys())[15:30]
    
        def build(self):
            return Builder.load_string(KV)
    
        def on_start(self):
            for name_tab in self.icons:
                self.root.ids.tabs.add_widget(Tab(text=name_tab))
    
        def on_tab_switch(
            self, instance_tabs, instance_tab, instance_tab_label, tab_text
        ):
            '''Called when switching tabs.
    
            :type instance_tabs: <kivymd.uix.tab.MDTabs object>;
            :param instance_tab: <__main__.Tab object>;
            :param instance_tab_label: <kivymd.uix.tab.MDTabsLabel object>;
            :param tab_text: text or name icon of tab;
            '''
    
            count_icon = [k for k, v in md_icons.items() if v == tab_text]
            instance_tab.ids.icon.icon = count_icon[0]
    
    
    Example().run()
    

    https://kivymd.readthedocs.io/en/latest/components/tabs/index.html#kivymd.uix.tab.MDTabs.on_tab_switch