Screen Management from Class

323 views
Skip to first unread message

Testo Usero

unread,
Jan 16, 2021, 3:37:31 PM1/16/21
to Kivy users support

I'm using KivyMD framework and I'm trying to manage screens from classes but I don't know how to do it. NavigationDrawer should be manageable in every screens.

I want to make, 5 different screens:

  • Home Screen for welcome message.
  • Football screen
  • Basketball screen
  • Volleyball screen
  • News screen

Here's example of my code:


from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen

from kivymd.app import MDApp

KV = '''

<ScrManage>:
    HomeScreen:
        name: 'home'
    FBScreen:
        name: 'football'
    BBScreen:
        name: 'basketball'
    VBScreen:
        name: 'volleyball'
    NScreen:
        name: 'news'

    ScrollView:

        MDList:

            OneLineListItem:
                text: "Home"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "home"

            OneLineListItem:
                icon: 'soccer'
                text: "Football"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "football"

            OneLineListItem:
                text: "Basketball"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "basketball"
            OneLineListItem:
                text: "Volleyball"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "volleyball"
            OneLineListItem:
                text: "News"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "news"


    MDNavigationDrawer:
        id: nav_drawer

        ContentNavigationDrawer:
            screen_manager: screen_manager
            nav_drawer: nav_drawer


<HomeScreen>:

    Screen:

        MDToolbar:
            id: toolbar
            pos_hint: {"top": 1}
            elevation: 10
            title: "Sports App"
            left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

        MDNavigationLayout:
            x: toolbar.height

            ScreenManager:
                id: screen_manager

<FBScreen>:
    Screen:
        name: "football"

        MDLabel:
            text: "Football"
            halign: "center"

<BBScreen>:
    Screen:
        name: "basketball"

        MDLabel:
            text: "Basketball"
            halign: "center"

<VBScreen>:
    Screen:
        name: "volleyball"

        MDLabel:
            text: "Volleyball"
            halign: "center"
<NScreen>:
    Screen:
        name: "news"

        MDLabel:
            text: "News"
            halign: "center"

'''

class HomeScreen(Screen):
    pass
class FBScreen(Screen):
    pass
class BBScreen(Screen):
    pass
class VBScreen(Screen):
    pass
class NScreen(Screen):
    pass



class ScrManage(ScreenManager):
    pass

class Sports(MDApp):
    def build(self):
        return Builder.load_string(KV)


Sports().run()


Returning empty screen. Just white.

Thanks.

Elliot Garbus

unread,
Jan 16, 2021, 4:22:49 PM1/16/21
to kivy-...@googlegroups.com

The screens need to be under a ScreenManager.

You have not defined a root widger.  From your code it is not clear to me what you are trying to do.  Here is a simple example that shows how screens work in a ScreenMangager.

 

 

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

kv =
"""
<MainScreen>:  # The definition of the class
    Button:
        on_release: root.manager.current = 'other'
        text: 'This is main,
\\nPress to go to the other Screen'
        font_size: 40

<AnotherScreen>:
    text: 'init'
    next_screen: 'init'
    Button:
        on_release: root.manager.current = root.next_screen
        text: root.text
        font_size: 40


ScreenManager:                          # The root widget
    MainScreen:                         # An instance of the class
        id: main_screen
        name: 'main'
        on_enter: self.counter += 1     # increment counter when main is entered.
    AnotherScreen:                      # An instance of the class
        name: 'other'
        text: 'This is the other screen,
\\nPress to go to yet another screen'
        next_screen: 'yet another'
        on_enter: print(f'The mainscreen counter from kv: {main_screen.counter}, widget: {self}')
    AnotherScreen:                      # An instance of the class
        name: 'yet another'
        text: 'This is yet another screen,
\\n press to go to main'
        next_screen: 'main'
        on_enter: self.show_mainscreen_counter()
"""


class MainScreen(Screen):
    counter = NumericProperty() 
# count the number of times the screen is entered.


class AnotherScreen(Screen):
   
def show_mainscreen_counter(self):
        
# to access the mainscreen counter you need to access the mainscreen, use get_screen
       
count = self.manager.get_screen('main').counter
       
print(f'The mainscreen counter from python: {count}, widget:{self}')


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


ScreenAttributeApp().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/c4e0f5d4-1807-445f-b385-b524751dc281o%40googlegroups.com.

 

kivy

unread,
Jan 16, 2021, 4:52:36 PM1/16/21
to Kivy users support
I changed my KV area with this code:
KV = '''
ScreenManager:
   HomeScreen:
       id: home
       name: 'home'
   FBScreen:
       id: fb
       name: 'fb'


    MDToolbar:
       id: toolbar
       pos_hint: {"top": 1}
       elevation: 10
       title: "Sports App"
       left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:
       x: toolbar.height
           
       MDNavigationDrawer:
           ScrollView:

                MDList:

                    OneLineListItem:
                       icon: 'soccer'
                       text: "Football"
                       on_press:
                           root.nav_drawer.set_state("close")
                           root.screen_manager.current = "home"

                    OneLineListItem:
                       text: "Basketball"
                       on_press:
                           root.nav_drawer.set_state("close")
                           root.screen_manager.current = "fb"



<HomeScreen>:
   text: 'Home screen'
   halign: 'center'

<FBScreen>:
   text: 'fb screen'
   halign: 'center'

'''

But it's say 
kivy.uix.screenmanager.ScreenManagerException: ScreenManager accepts only Screen widget.




17 Ocak 2021 Pazar 00:22:49 UTC+3 tarihinde ElliotG yazdı:

To unsubscribe from this group and stop receiving emails from it, send an email to kivy-...@googlegroups.com.

ElliotG

unread,
Jan 16, 2021, 5:15:10 PM1/16/21
to Kivy users support
You have this code under the ScreenManager, but not part of a screen. (MDToobar... )
Looking at this code, suggests it is something you want on top of all of the screens, is this correct.

If that is the case you might want to have a Layout as the root widget,  your toolbar, and then the screen manager.
Something like:

BoxLayout:
    orientation: 'vertical'
    MDToolbar... and all the code under it...

   ScreeenManager:
      # Screens...


   



kivy

unread,
Jan 16, 2021, 5:51:43 PM1/16/21
to Kivy users support
I updated my code like this:

KV = '''

BoxLayout:
   MDToolbar:
       id: toolbar
       pos_hint: {"top": 1}
       elevation: 10
       title: "Sports App"
       left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:
       x: toolbar.height
           
       MDNavigationDrawer:
           id: nav_drawer
           ScrollView:

                MDList:

                    OneLineListItem:
                       icon: 'soccer'
                       text: "Football"
                       on_press:
                           root.nav_drawer.set_state("close")
                           root.screen_manager.current = "home"

                    OneLineListItem:
                       text: "Basketball"
                       on_press:
                           root.nav_drawer.set_state("close")
                           root.screen_manager.current = "fb"

    ScreenManager:
       HomeScreen:
           id: home
           name: 'home'
       FBScreen:
           id: fb
           name: 'fb'




<HomeScreen>:
   text: 'Home screen'
   halign: 'center'

<FBScreen>:
   text: 'fb screen'
   halign: 'center'

'''

It's running now but toolbar width is like half of the window width. And I'm clicking ListItem's getting error: 
 AttributeError: 'BoxLayout' object has no attribute 'nav_drawer'



17 Ocak 2021 Pazar 01:15:10 UTC+3 tarihinde ElliotG yazdı:

ElliotG

unread,
Jan 16, 2021, 6:48:09 PM1/16/21
to Kivy users support
Right under the BoxLayout
orientation: ‘vertical’

Do not put root. in front of the id. Just nav_drawer.set_state(...)
You will also need to create an I’d under the screen manager. 

kivy

unread,
Jan 17, 2021, 7:11:03 AM1/17/21
to Kivy users support
I did it. But now, scrollview is start from half of the screen. And I can click MDList items, but screen doesn't changing. My code is like that now:

KV = '''

BoxLayout:
   orientation: 'vertical'
   MDToolbar:
       id: toolbar
       pos_hint: {"top": 1}
       elevation: 10
       title: "Sports App"
       left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:
       x: toolbar.height
           
       MDNavigationDrawer:
           id: nav_drawer
           ScrollView:

                MDList:

                    OneLineListItem:
                       icon: 'soccer'
                       text: "Football"
                       on_press:
                           nav_drawer.set_state("close")
                           screen_manager.current = "home"

                    OneLineListItem:
                       text: "Basketball"
                       on_press:
                           nav_drawer.set_state("close")
                           screen_manager.current = "fb"

    ScreenManager:
       id: screen_manager
       HomeScreen:
           id: home
           name: 'home'
       FBScreen:
           id: fb
           name: 'fb'




<HomeScreen>:
   text: 'Home screen'
   halign: 'center'

<FBScreen>:
   text: 'fb screen'
   halign: 'center'

'''



17 Ocak 2021 Pazar 02:48:09 UTC+3 tarihinde ElliotG yazdı:

ElliotG

unread,
Jan 17, 2021, 11:56:39 AM1/17/21
to Kivy users support
I removed some lines of kv that were not needed, changed the position of the ScreenManager, and added Labels to you Screens.


from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

from kivymd.app import MDApp

kv = '''

BoxLayout:
    orientation: 'vertical'
    MDToolbar:
        id: toolbar
        elevation: 10
        title: "Sports App"
        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:
        ScreenManager:
            id: screen_manager
            HomeScreen:
                id: home
                name: 'home'
            FBScreen:
                id: fb
                name: 'fb'
                
        MDNavigationDrawer:
            id: nav_drawer
            ScrollView:
                MDList:
                    OneLineListItem:
                        icon: 'soccer'
                        text: "Football"
                        on_press:
                            nav_drawer.set_state("close")
                            screen_manager.current = "home"
                    OneLineListItem:
                        text: "Basketball"
                        on_press:
                            nav_drawer.set_state("close")
                            screen_manager.current = "fb"

<HomeScreen>:
    MDLabel:
        text: 'Home screen'
        halign: 'center'

<FBScreen>:
    MDLabel:
        text: 'fb screen'
        halign: 'center'

'''


class HomeScreen(Screen):
    pass


class FBScreen(Screen):
    pass


class BBScreen(Screen):
    pass


class VBScreen(Screen):
    pass


class NScreen(Screen):
    pass


class ScrManage(ScreenManager):
    pass


class Sports(MDApp):
    def build(self):
        return Builder.load_string(kv)


Sports().run()

kivy

unread,
Jan 17, 2021, 1:28:00 PM1/17/21
to Kivy users support
It works. Thank you so much ElliotG!

17 Ocak 2021 Pazar 19:56:39 UTC+3 tarihinde ElliotG yazdı:
Reply all
Reply to author
Forward
0 new messages