I can't change the screen with MDFlatButton in a loop

173 Views Asked by At

I can't change screen by the buttons that I define in a for loop and it shows this error: AttributeError: type object 'ScreenManager' has no attribute 'manager' I want to define it in the .py file because it must be in the for loop to create a button for each item. you can find the code below. please assist

from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty,StringProperty
from kivymd.uix.list import MDList,OneLineListItem,TwoLineListItem
from kivymd.uix.button import MDFlatButton
#from kivy.uix.scrollview import ScrollView
#import json
from kivy.storage.jsonstore import JsonStore
from kivy.clock import Clock,mainthread
import sys
import os.path
import json

file = sys.argv[0]
foldername =os.path.dirname(file)

store = JsonStore(foldername+"/data.json")

screen_helper = """
ScreenManager:

    MainScreen: 
    AddScreen: 
    PerScreen: 
    TripDetail:

<MainScreen>:
    name:  'Main'
    MDRectangleFlatButton:
        text: 'add new'
        pos_hint: {'center_x':0.5,'center_y':0.5}
        on_press: root.manager.current = 'Add'
    MDRectangleFlatButton:
        text: 'pervius cal'
        pos_hint: {'center_x':0.5,'center_y':0.2}
        on_press: root.manager.current = 'Per'
<AddScreen>:
    id: addScreen
    name: 'Add'
    MDLabel:
        text: 'add new'
        halign: 'center'
        pos_hint:{'center_x':0.5,'center_y':0.9}
    MDRectangleFlatButton:
        text: 'back'
        pos_hint:{'center_x':0.5,'center_y':0.1}
        on_press: root.manager.current = 'Main'
    MDTextField:
        id: addNewCal
        hint_text: "Enter cal name:"
        pos_hint: {'center_x': 0.5,'center_y':0.6}
        size_hint_x: None
        width:300
    MDRectangleFlatButton:
        text: 'save'
        pos_hint:{'center_x':0.5,'center_y':0.4}
        on_press: root.save()
<PerScreen>:
    name: 'Per'
    ScrollView:
        size_hint_y:None
        height: 400
        MDList:
            id: tripList
    MDLabel:
        text: 'pervius cal'
        halign: 'center'
        pos_hint: {'center_x': 0.3,'center_y':0.9}
    MDRectangleFlatButton:
        text: 'back'
        pos_hint: {'center_x': 0.7,'center_y':0.9}
        on_press: root.manager.current = 'Main'
<TripDetail>:
    name: 'TripDetail'
    MDLabel:
        text: 'test'
"""

class MainScreen(Screen):
    pass

class AddScreen(Screen):
    screenManager = ObjectProperty(None)
    def save(self):
        calName = self.ids.addNewCal.text
        trip = {"tripname":calName,"persons":[],"sumCost": "0","personCost":[]}
        with open(foldername+"/data.json","r") as f:
            data = json.load(f)
            data["trips"].append(trip)
        with open(foldername+"/data.json","w") as f:
            json.dump(data,f,indent = 2)
        print(calName)

    pass

class PerScreen(Screen):
    
    @mainthread

    def on_enter(self, *args):
        """Event fired when the screen is displayed: the entering animation is
        complete."""
        
        def on_enter(interval):
            with open(foldername+"/data.json","r") as f:
                data = json.load(f)
                trip = data["trips"]
            self.ids.tripList.clear_widgets()
                
            **for i in range(len(trip)):
                self.ids.tripList.add_widget(MDFlatButton(text=trip[i]["tripname"],on_press = showTrip))
        def showTrip(self,*args):
            ScreenManager.manager.current = 'TripDetail'**
    
            

        Clock.schedule_once(on_enter)
class TripDetail(Screen):
    pass

sm = ScreenManager()
sm.add_widget(MainScreen(name='Main'))
sm.add_widget(AddScreen(name='Add'))
sm.add_widget(PerScreen(name='Per'))
sm.add_widget(TripDetail(name='TripDetail'))


class DongApp(MDApp):
    def build(self):
        screen = Builder.load_string(screen_helper)
        return screen  
        
    def showTrip(self):
        self.sm.current = 'TripDetail'


DongApp().run()
1

There are 1 best solutions below

2
On

The error message is telling you what you are doing wrong. The ScreenManager class has no managerattribute. You need to set the current attribute of the ScreenManager instance, which you get from the MDApp.

Try changing:

ScreenManager.manager.current = 'TripDetail'

to:

MDApp.get_running_app().root.current = 'TripDetail'