【发布时间】:2017-03-19 02:25:21
【问题描述】:
我正在通过开发一个应用程序来注册锻炼程序来试验 kivy,在屏幕管理器中有几个屏幕。但是,在运行代码时,我得到了 ScreenManagerException:
kivy.uix.screenmanager.ScreenManagerException: No Screen with name "('Suplementos', <kivy.uix.button.Button object at 0xb3d3341c>)".
该应用目前由以下代码组成(python 2.7 + kivy 1.9):
main.py
#coding:utf-8
from functools import partial
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView
import time
class TelaInicial(Screen):
layout_telainicial = ObjectProperty(None)
def __init__(self, **kwargs):
super(TelaInicial, self).__init__(**kwargs)
opcoes = [
'Suplementos',
'Cardiovascular',
'Novo treino'
]
for opt in opcoes:
Opcao = Button(
text=str(opt),
size_hint_y=None,
height=60,
)
Opcao.bind(on_press=partial(self.ir_para, opt))
self.ids.layout_telainicial.add_widget(Opcao)
def ir_para(self, *args):
self.parent.current = str(args)
class Suplementos(Screen):
layout_suplementos = ObjectProperty(None)
def __init__(self, **kwargs):
hora = time.asctime()
super(Suplementos, self).__init__(**kwargs)
mostrar_hora = Label(text=str(hora))
self.ids.layout_suplementos.add_widget(mostrar_hora)
class Cardiovascular(Screen):
layout_cardiovascular = ObjectProperty(None)
def __init__(self, **kwargs):
hora = time.asctime()
super(Cardiovascular, self).__init__(**kwargs)
mostrar_hora = Label(text=str(hora))
self.ids.layout_cardiovascular.add_widget(mostrar_hora)
class NovoTreino(Screen):
layout_novotreino = ObjectProperty(None)
def __init__(self, **kwargs):
super(NovoTreino, self).__init__(**kwargs)
AdicionarExercicio = Button(
text='+',
size_hint_y=None,
height=60,
)
AdicionarExercicio.bind(on_press=lambda a: self.NovoExercicio)
self.ids.layout_novotreino.add_widget(AdicionarExercicio)
def NovoExercicio(self, *args):
self.parent.current = 'Seleção de exercícios'
class SelecaoExercicio(Screen):
pass
class GerenciadorApp(App):
def build(self):
MyScreenManager = ScreenManager()
MyScreenManager.add_widget(TelaInicial())
MyScreenManager.add_widget(Suplementos())
MyScreenManager.add_widget(Cardiovascular())
MyScreenManager.add_widget(NovoTreino())
MyScreenManager.add_widget(SelecaoExercicio())
return MyScreenManager
GerenciadorApp().run()
gerenciador.kv
<TelaInicial>
name: 'Tela inicial'
ScrollView:
GridLayout:
id: layout_telainicial
cols: 1
padding: 10
spacing: 10
size_hint: 1, None
height: self.minimum_height
<Suplementos>
name: 'Suplementos'
ScrollView:
GridLayout:
id: layout_suplementos
cols: 1
padding: 10
spacing: 10
size_hint: 1, None
height: self.minimum_height
Label:
text: 'Registro de suplementos'
<Cardiovascular>
name: 'Cardiovascular'
ScrollView:
GridLayout:
id: layout_cardiovascular
cols: 1
padding: 10
spacing: 10
size_hint: 1, None
height: self.minimum_height
Label:
text: 'Exercício cardiovascular'
<NovoTreino>
name: 'Novo treino'
ScrollView:
GridLayout:
id: layout_novotreino
cols: 1
padding: 10
spacing: 10
size_hint: 1, None
height: self.minimum_height
Label:
text: 'Treino de musculação'
<SelecaoExercicio>
name: 'Seleção de exercícios'
ScrollView:
GridLayout:
id: layout_selecaoexercicios
cols: 1
padding: 10
spacing: 10
size_hint: 1, None
height: self.minimum_height
在以前的代码版本中,我还尝试了一个 lambda 函数而不是 partial() 函数,它在 TelaInicial 类构造函数中用于绑定“on_press”按钮的属性:
class TelaInicial(Screen):
layout_telainicial = ObjectProperty(None)
def __init__(self, **kwargs):
super(TelaInicial, self).__init__(**kwargs)
opcoes = [
'Suplementos',
'Cardiovascular',
'Novo treino'
]
for opt in opcoes:
Opcao = Button(
text=str(opt),
size_hint_y=None,
height=60,
)
Opcao.bind(on_press=self.ir_para(opt))
self.ids.layout_telainicial.add_widget(Opcao)
def ir_para(self, destino, *args):
self.parent.current = str(destino)
这将始终为所有按钮返回选项列表中的最后一个屏幕“NovoTreino”,而不是每个按钮标识的屏幕。
为什么代码在每种情况下都不能正常工作 - 我该如何解决?
【问题讨论】: