Kivy ScreenManager can't reference class from .py file class any more. Attribute error: 'super' has

Kivy ScreenManager can't reference class from .py file class any more. Attribute error: 'super' has

我刚刚开始使用 kivy 在 python 开发我的第一个应用程序。除了我的主 py 之外,我还生成了应用程序的总体布局以及 python 文件中的一些逻辑,以将所有内容分开一些。这工作得很好,应用 运行 没有任何问题。我想在点击提供额外信息的按钮时添加一些屏幕。设法做到了这一点,但现在应用程序在点击添加额外屏幕之前有效的按钮时崩溃了。这些按钮使用 类,但未在 main.py 中实现,而是在辅助文件中实现。就像我解释的那样,他们在添加 ScreenManager 之前工作。这是我得到的错误的简短版本:AttributeError: 'super' object has no attribute '__getattr__'

Main.py: peenomat.py

import kivy
# -*- coding: iso-8859-1 -*-
from kivy.app import App

from kivy.uix.button import Label
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.uix.anchorlayout import AnchorLayout
from kivy.core.text import LabelBase
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty
from kivy.properties import ObjectProperty
from kivy.config import Config


Builder.load_file('Header.kv')
Builder.load_file('Statusbar.kv')
Builder.load_file('Inputparameters.kv')
Builder.load_file('Outputparameters.kv')
Builder.load_file('Extra.kv')
#loading main kv
Builder.load_file('peenomat.kv')


class Peenomat(Screen):
    pass


class Instruction(Screen):
    pass

class Additional(Screen):
    pass

# Create the screen manager
sm = ScreenManager()
sm.add_widget(Peenomat(name='peenomat'))
sm.add_widget(Instruction(name='instruction'))
sm.add_widget(Additional(name='additional'))


class PeenomatApp(App):
    def build(self):
        self.icon = 'icon.png'
        #return pm
        return sm
        #return Peenomat()

if __name__=="__main__":

    PeenomatApp().run()

主要kv.file: peenomat.kv

<Peenomat>

    AnchorLayout:
        anchor_x: 'left'
        anchor_y: 'bottom'
        GridLayout:
            cols: 1
 
            InputParameters:
                id:_input_parameters

            StatusBar:
                id:_status_bar
                       
                

<Instruction>:
    AnchorLayout:
        anchor_x: 'left'
        anchor_y: 'bottom'
        GridLayout:
            cols: 1
            canvas.before:
            Label:
                text:

            Button:
                text: 
                on_release:
                    app.root.current = "peenomat"
                    app.root.transition.direction = "up"

<Additional>:
    AnchorLayout:
        anchor_x: 'left'
        anchor_y: 'bottom'
        GridLayout:
            cols: 1
            Button:
                text: 
                on_release:
                    app.root.current = "peenomat"
                    app.root.transition.direction = "left"

我在其中引用按钮功能的 .kv 文件: statusbar.kv

#: import statusbar StatusBar

<StatusBar@BoxLayout>

    orientation:'horizontal'
    padding:
    spacing: 

    Label:
        size_hint: 0.05, 1

    Button:
        text: 'Leeren'
        on_press: root.btn_clear()

    Button:
        text: "Mehr"
        on_release:
            app.root.current = "additional"
            app.root.transition.direction ="right"


    Button:
        text: u"Los schl\u00e4gts"
        on_press: root.btn_submit()

    Button:
        text: "?"
        on_release:
            app.root.current = "instruction"
            app.root.transition.direction ="down"

最后是提供 类 的 python 文件,我在其中生成现在崩溃的按钮的功能: StatusBAr.py

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
from kivy.app import App
from kivy.lang import Builder
#from Inputparameters import InputParameters


ver = ''
class InputParameters(GridLayout):
    verfahren =ObjectProperty(None)

    def on_state(self, togglebutton):
        tb = togglebutton
        global ver
        if tb.state == 'down':
            self.verfahren = tb.text
            ver = tb.text
            print(self.verfahren, ver)
            return self.verfahren


class StatusBar(BoxLayout):
    #InputGrößen
    group_mode = False
    prozess = ObjectProperty(None)
    vorbehandlung = ObjectProperty(None)
    material = ObjectProperty(None)
    haerte = ObjectProperty(None)
    rauheit = ObjectProperty(None)
    verfahren = ObjectProperty(None)

    #OutputGrößen
    frequency = StringProperty(None)
    speed = StringProperty(None)
    hub = StringProperty(None)

    def btn_submit(self):
        global ver
        ip = App.get_running_app().root.ids._input_parameters
        op = App.get_running_app().root.ids._output_parameters

        frequenz = 0
        if ip.haerte.value < 50:
            op.frequency = str(180) +" Hz"
            op.speed = str(2.4) +" mm/s"
            op.hub = str(3.4) + " mm"
        elif ip.haerte.value < 60:
            op.frequency = str(200) +" Hz"
            op.speed = str(3.5) + " mm/s"
            op.hub = str(5.23) + " mm"
        else:
            op.frequency = str(220) +" Hz"
            op.speed = str(1.2) + " mm/s"
            op.hub = str(7.2) + " mm"
        #control to see if right value is taken
        print(op.frequency)

    def btn_clear(self):
        ip = App.get_running_app().root.ids._input_parameters
        op = App.get_running_app().root.ids._output_parameters
        ip.pro1.state = "normal"
        ip.pro2.state = "normal"
        ip.pro3.state = "normal"
        ip.material.text = "Auswahl treffen"
        ip.vorbehandlung.text = "Auswahl treffen"
        ip.haerte.value = 55
        ip.rauheit.value = 5.5
        op.frequency = "---"
        op.speed = "---"
        op.hub = "---"

所以如果使用提交或清除按钮,我会收到以下错误:

[INFO   ] [Base        ] Leaving application in progress...
 Traceback (most recent call last):
   File "kivy\properties.pyx", line 860, in kivy.properties.ObservableDict.__getattr__
 KeyError: '_input_parameters'
 
 During handling of the above exception, another exception occurred:
 
 Traceback (most recent call last):
   File "C:/Users/schum/Dokumente/TUD/Masterthesis/Peenomat.py", line 79, in <module>
     PeenomatApp().run()
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\app.py", line 855, in run
     runTouchApp()
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\base.py", line 504, in runTouchApp
     EventLoop.window.mainloop()
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\core\window\window_sdl2.py", line 747, in mainloop
     self._mainloop()
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\core\window\window_sdl2.py", line 479, in _mainloop
     EventLoop.idle()
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\base.py", line 342, in idle
     self.dispatch_input()
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\base.py", line 327, in dispatch_input
     post_dispatch_input(*pop(0))
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\base.py", line 233, in post_dispatch_input
     listener.dispatch('on_motion', etype, me)
   File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\core\window\__init__.py", line 1402, in on_motion
     self.dispatch('on_touch_down', me)
   File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\core\window\__init__.py", line 1418, in on_touch_down
     if w.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\uix\screenmanager.py", line 1191, in on_touch_down
     return super(ScreenManager, self).on_touch_down(touch)
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\uix\widget.py", line 549, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\uix\relativelayout.py", line 288, in on_touch_down
     ret = super(RelativeLayout, self).on_touch_down(touch)
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\uix\widget.py", line 549, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\uix\widget.py", line 549, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\uix\widget.py", line 549, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\uix\widget.py", line 549, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\uix\behaviors\button.py", line 151, in on_touch_down
     self.dispatch('on_press')
   File "kivy\_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch
   File "kivy\_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
   File "kivy\_event.pyx", line 1098, in kivy._event.EventObservers._dispatch
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\lang\builder.py", line 64, in custom_callback
     exec(__kvlang__.co_value, idmap)
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\Statusbar.kv", line 38, in <module>
     on_press: root.btn_submit()
   File "C:\Users\schum\Dokumente\TUD\Masterthesis\StatusBar.py", line 41, in btn_submit
     ip = App.get_running_app().root.ids._input_parameters
   File "kivy\properties.pyx", line 863, in kivy.properties.ObservableDict.__getattr__
 AttributeError: 'super' object has no attribute '__getattr__'

按钮的功能是从中获取选定的参数。kv.file

inputparameters.kv

#: import statusbar StatusBar

<InputParameters@GridLayout>
    #Initialisierung .py zu .kv Ids
    prozess: _prozess
    pro1: _prozess1
    pro2: _prozess2
    pro3: _prozess3
    vorbehandlung: _vorbehandlung
    material: _material
    haerte: _haerte
    rauheit: _rauheit

    cols: 2
    padding: 25
    spacing: 10

    #Prozess
    Label:
        text:'Prozess:              '

    BoxLayout:
        orientation: 'horizontal'
        id: _prozess

        ToggleButton:
            id:_prozess1
            text:'P-MOH'
            group: "proc_group"
            on_state: root.on_state(self)

        ToggleButton:
            id:_prozess2
            text:'E-MOH'
            group: "proc_group"
            on_state: root.on_state(self)

        ToggleButton:
            id:_prozess3
            text:'PE-MOH'
            group: "proc_group"
            on_state: root.on_state(self)

    #Material

    Label:
        text: 'Material:'

    Spinner:
        id: _material
        text: "Auswahl treffen"
        values: ['1.2379', 'Gusseisen', 'Kautschuk', 'Carbon', 'Adamantium']

    # Herstellschritte
    Label:
        text:'Fertigungsschritte:'

    Spinner:
        id: _vorbehandlung
        text: "Auswahl treffen"
        values: [u'Fr\u00e4sen', 'Erodieren', 'Schleifen', 'Polieren']

    # Haerte
    Label:
        text: u"H\u00e4rte:"

    BoxLayout:
        orientation: 'vertical'

        Label:
            text: str(_haerte.value) + ' HRC'

        Slider:
            id: _haerte
            min: 45
            max: 65
            step: 1
            value_track: True

    # Rauheit
    Label:
        text:'Rauheit:'              

    BoxLayout:
        orientation: 'vertical'
        Label:
            text: str("%.1f" % _rauheit.value) + ' Rz' #eine Nachkommastelle

        Slider:
            id: _rauheit
            min: 1
            max: 10
            value_track: True

奇怪的是切换按钮仍然可以使用 statusbar.py 中的函数 generate 并完成它们的工作。 我希望你能帮我解决这个问题,甚至不知道从哪里开始...... 提前致谢!

ids 字典是为 kv 文件中的每个规则创建的,那些 ids 被放置在该规则根的字典中。所以 _input_parameters id 仅在 Peenomat 实例的 ids 中。

所以,我认为你需要改变:

    ip = App.get_running_app().root.ids._input_parameters

类似于:

    ip = App.get_running_app().root.get_screen('peenomat').ids._input_parameters

你的ApprootScreenManagerget_screen('peenomat')得到PeenomatScreen的实例。