如何解决Kivy ScreenManager不再引用.py文件类中的类属性错误:“超级”具有
我刚刚开始使用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',line 1418,in on_touch_down
if w.dispatch('on_touch_down',touch):
File "kivy\_event.pyx",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',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,in kivy._event.EventDispatcher.dispatch
File "C:\Users\schum\Dokumente\TUD\Masterthesis\venv\lib\site-packages\kivy\uix\widget.py",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中的generatet函数来完成其工作。 希望您能帮我解决这个问题,甚至不知道从哪里开始。 预先谢谢!!
解决方法
为ids
文件中的每个规则创建kv
字典,并将那些ids
放在该规则根目录的字典中。因此_input_parameters
id
仅在ids
实例的Peenomat
中。
所以,我认为您需要更改:
ip = App.get_running_app().root.ids._input_parameters
类似:
ip = App.get_running_app().root.get_screen('peenomat').ids._input_parameters
您的root
中的App
是ScreenManager
,而get_screen('peenomat')
获得了Peenomat
Screen
实例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。