I have 3 Screens in my kivy application and in the second screen i want to put a graph which is a widget. I have my own class for this graph. The goal is do display 3 separate graphs in one screen.
I’m pretty sure there is some problem with the id from the class Graph. I tried to use self.ids.get_screen or just copying everything from the class Graph to the class SecondScreen. Sometimes i get a different error but normally this one.
Can maybe someone explain IDs to me? I think i am very confused what to do when i have to use an id from one class in another. Sadly the other questions with the same error didn’t really help
Thanks a lot for helping!
This is my error:
Traceback (most recent call last): File "kivy/properties.pyx", line 961, in kivy.properties.ObservableDict.__getattr__ KeyError: 'boxgraph' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/valentin/Desktop/Masterarbeit/python-screenmanager/screenmanager.py", line 57, in <module> TestApp().run() File "/home/valentin/.local/lib/python3.8/site-packages/kivy/app.py", line 954, in run self._run_prepare() File "/home/valentin/.local/lib/python3.8/site-packages/kivy/app.py", line 924, in _run_prepare root = self.build() File "/home/valentin/Desktop/Masterarbeit/python-screenmanager/screenmanager.py", line 54, in build return Project() File "/home/valentin/.local/lib/python3.8/site-packages/kivy/uix/boxlayout.py", line 145, in __init__ super(BoxLayout, self).__init__(**kwargs) File "/home/valentin/.local/lib/python3.8/site-packages/kivy/uix/layout.py", line 76, in __init__ super(Layout, self).__init__(**kwargs) File "/home/valentin/.local/lib/python3.8/site-packages/kivy/uix/widget.py", line 366, in __init__ self.apply_class_lang_rules( File "/home/valentin/.local/lib/python3.8/site-packages/kivy/uix/widget.py", line 470, in apply_class_lang_rules Builder.apply( File "/home/valentin/.local/lib/python3.8/site-packages/kivy/lang/builder.py", line 540, in apply self._apply_rule( File "/home/valentin/.local/lib/python3.8/site-packages/kivy/lang/builder.py", line 662, in _apply_rule self._apply_rule( File "/home/valentin/.local/lib/python3.8/site-packages/kivy/lang/builder.py", line 660, in _apply_rule child.apply_class_lang_rules( File "/home/valentin/.local/lib/python3.8/site-packages/kivy/uix/widget.py", line 470, in apply_class_lang_rules Builder.apply( File "/home/valentin/.local/lib/python3.8/site-packages/kivy/lang/builder.py", line 540, in apply self._apply_rule( File "/home/valentin/.local/lib/python3.8/site-packages/kivy/lang/builder.py", line 658, in _apply_rule child = cls(__no_builder=True) File "/home/valentin/Desktop/Masterarbeit/python-screenmanager/screenmanager.py", line 40, in __init__ box = self.ids.boxgraph File "kivy/properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__ AttributeError: 'super' object has no attribute '__getattr__'
This are some code snippets:
python code:
class ScreenManager(ScreenManager): pass class Project(BoxLayout): pass class Graph(FloatLayout): def __init__(self, **kwargs): super().__init__(**kwargs) box = self.ids.boxgraph box.add_widget(FigureCanvasKivyAgg(plt.gcf())) def save(self): pass Builder.load_file("screenmanager.kv") class TestApp(MDApp): title = "Kivy Project" def build(self): self.theme_cls.theme_style ="Dark" self.theme_cls.primary_palette = "BlueGray" return Project() if __name__ == '__main__': TestApp().run()
kivy code:
<Project>: orientation: "vertical" canvas.before: Color: rgb: .6, .6, .6 Rectangle: pos: self.pos size: self.size SomeMenu_ActionBar: id: ActionBar ScreenManager: id: sm WelcomeScreen: FirstScreen: SecondScreen: /.../ <SecondScreen>: id: second name: 'second' Graph: <Graph>: id: boxgraph BoxLayout: size_hint_y: .9 pos_hint: {"top": 1} BoxLayout: size_hint_y: .1 TextInput: id: name multiline: False Button: text: "Save" on_release: root.save()
EDIT: ok i figured some stuff out. The ids library contains those ids
{‘ActionBar’: <WeakProxy to <kivy.factory.SomeMenu_ActionBar object at 0x7f9ffc677c10>>, ‘sm’: <WeakProxy to <kivy.uix.screenmanager.ScreenManager object at 0x7f9ff4175820>>}
so i think i need to add the graph id there too. Still not sure how, but im still on it.
I deleted the Graph: from Second Screen. Added Graph: with an id to ScreenManager:
ScreenManager: id: sm WelcomeScreen: FirstScreen: SecondScreen: Graph: id: graph_screen
Now i have this AttributeError:
AttributeError: ‘NoneType’ object has no attribute ‘ids’
Advertisement
Answer
Ok i found the answer
Here is only the changed parts of my code: python file:
class Graph(BoxLayout): def __init__(self, **kwargs): super().__init__(**kwargs) self.add_widget(FigureCanvasKivyAgg(plt.gcf()))
kv-file:
ScreenManager: id: sm WelcomeScreen: FirstScreen: SecondScreen: <SecondScreen>: id: second name: 'second' BoxLayout: orientation: "vertical" Graph:
I dont need a definition of Graph in the kv-File since everything is handled in the python file