'How to put a Graph into a Screen(Manager) with kivy
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'
Solution 1:[1]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |