【问题标题】:Kivy screenmanager "No Screen with name" error when redirecting重定向时 Kivy 屏幕管理器“没有名称的屏幕”错误
【发布时间】: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”,而不是每个按钮标识的屏幕。

为什么代码在每种情况下都不能正常工作 - 我该如何解决?

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    问题在于,当您只需要 args 的第一项时,您将 screenmanagers 当前设置为整个 args 列表。

    >>> print(args)
    ('Suplementos', <kivy.uix.button.Button object at 0xb3d3341c>)
    >>> print(args[0])
    'Suplementos'
    

    所以你需要的是:

    def ir_para(self, *args):
        self.parent.current = str(args[0])
    

    【讨论】:

    • @BernardoChrispimBaront 你很高兴 :) 谁说这应该很复杂
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    相关资源
    最近更新 更多