如何使用 kivy 将图形放入屏幕(管理器)

How to put a Graph into a Screen(Manager) with kivy

我的 kivy 应用程序中有 3 个屏幕,在第二个屏幕中我想放置一个图形,它是一个小部件。对于这张图,我有自己的 class。目标是在一个屏幕上显示 3 个独立的图表。

我很确定 class 图中的 id 有问题。我尝试使用 self.ids.get_screen 或只是将 class Graph 中的所有内容复制到 class SecondScreen。有时我会得到一个不同的错误,但通常是这个。

有人可以向我解释 ID 吗?我想我很困惑当我必须在另一个中使用一个 class 中的 id 时该怎么做。可悲的是,具有相同错误的其他问题并没有真正帮助

非常感谢您的帮助!

这是我的错误:

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__'

这是一些代码片段:

python代码:

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代码:

<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()

编辑: 好的,我想通了一些东西。 ids 库包含那些 ids

{'ActionBar': <WeakProxy to <kivy.factory.SomeMenu_ActionBar object at 0x7f9ffc677c10>>, 'sm': <WeakProxy to <kivy.uix.screenmanager.ScreenManager object at 0x7f9ff4175820>>}

所以我想我也需要在那里添加图形 ID。仍然不确定如何,但我仍在努力。

我从第二个屏幕删除了图表:。添加图形:带有 id 到 ScreenManager:

ScreenManager:
     id: sm
     WelcomeScreen:
     FirstScreen:
     SecondScreen:
         Graph:
             id: graph_screen

现在我有这个 AttributeError:

AttributeError: 'NoneType' object has no attribute 'ids'

好的,我找到答案了

这里只是我的代码更改的部分: python 文件:

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:

我不需要在 kv-File 中定义图形,因为所有内容都在 python 文件中处理