我的屏幕管理器无法返回主屏幕

时间:2019-07-06 18:39:27

标签: python python-3.x kivy

您好,我是Python和Kivy的新手。为了练习,我试图在单击新的Kivy应用程序的按钮时自动生成一个新屏幕。在新屏幕中,我生成两个按钮。他们应该将我发送回主页,但是当我单击它们时,会发生以下情况:

  File "~/screenmanager.py", line 1064, in get_screen
     raise ScreenManagerException('No Screen with name "%s".' % name)
 kivy.uix.screenmanager.ScreenManagerException: No Screen with name "home_screen"

能否请您检查代码并解释我做错了什么?

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.button import ButtonBehavior, Button
from kivy.uix.image import Image
from kivy.uix.gridlayout import GridLayout


class MyButton(ButtonBehavior, Image):

    def __init__(self, **kwargs):
        super(MyButton, self).__init__(**kwargs)
        self.source = "img/spot.png"

    def on_release(self):
        sm = MyScreenManager()
        on_release = sm.change_screen(name="home_screen")
        self.source = "img/settings.png"

class ImageButton(ButtonBehavior, Image):
    pass

class MyGrids(GridLayout):

    def Grid_1x2():
        obj = GridLayout(cols=1)
        obj.add_widget(MyButton(
            #on_release = sm.change_screen(name="home_screen")
                    ))
        obj.add_widget(Button(
            text="World 4"
            #on_release = sm.change_screen(name="home_screen")
            ))
        return obj

class Homescreen(Screen):
    pass

class Newscreen(Screen):
    pass

class Settingscreen(Screen):
    pass

class MyScreenManager(ScreenManager):

#    def __init__(self, **kwargs):
#        super(MyScreenManager, self).__init__(**kwargs)


    def change_screen(self, name):
         self.current = name

    def new_screen(self):
        name="new_screen"
        mynewscreen = Newscreen(name=name)
        layout = MyGrids.Grid_1x2()
        mynewscreen.add_widget(layout)
        self.add_widget(mynewscreen)
        self.current = name

GUI = Builder.load_file("main.kv")

class Main(App):

    def build(self):
        #print(self.root.ids)
        return GUI


Main().run()

我的Main.kv是

#: include kv/homescreen.kv
#: include kv/settingscreen.kv


MyScreenManager:
    Homescreen:
        name: "home_screen"
        id: home_screen
    Settingscreen:
        name: "setting_screen"
        id: setting_screen

我的主屏幕是:

<Homescreen>:

    FloatLayout:
        GridLayout:
            canvas.before:
                Color:
                    rgba: 0.99, 0.99, 0.99, 1
                Rectangle:
                    # self here refers to the widget i.e FloatLayout
                    pos: self.pos
                    size: self.size
            cols: 1
            pos_hint: {"top":1, "left": 1}
            size_hint: 1, .05

        GridLayout:
            canvas.before:
                Color:
                    rgba: 0.99, 0.99, 0.99, 1
                Rectangle:
                    # self here refers to the widget i.e FloatLayout
                    pos: self.pos
                    size: self.size
            cols: 1
            pos_hint: {"top":0.95, "left": 1}
            size_hint: 1, .15

            GridLayout:
                rows: 1
                cols: 5
                pos_hint: {'left': .2}
                size_hint: 0.6, .15
                Label:
                    canvas.before:
                        Color:
                            rgba: 0.99, 0.99, 0.99, 1
                        Rectangle:
                            # self here refers to the widget i.e FloatLayout
                            pos: self.pos
                            size: self.size
                ImageButton:
                    id: left
                    source: "img/arrow-left.png"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y
                    on_release:
                        app.root.change_screen("setting_screen")

                Image:
                    source: "img/spot.png"

                ImageButton:
                    id: right
                    source: "img/arrow-right.png"
                    center_x: self.parent.center_x
                    center_y: self.parent.center_y
                    on_release:
                        app.root.change_screen("setting_screen")

                Label:
                    canvas.before:
                        Color:
                            rgba: 0.99, 0.99, 0.99, 1
                        Rectangle:
                            # self here refers to the widget i.e FloatLayout
                            pos: self.pos
                            size: self.size

        GridLayout:
            canvas.before:
                Color:
                    rgba: 0.99, 0.99, 0.99, 1
                Rectangle:
                    # self here refers to the widget i.e FloatLayout
                    pos: self.pos
                    size: self.size
            cols: 1
            pos_hint: {"top":0.8, "left": 1}
            size_hint:1, .2

        GridLayout:
            canvas.before:
                Color:
                    rgba: 0.99, 0.99, 0.99, 1
                Rectangle:
                    # self here refers to the widget i.e FloatLayout
                    pos: self.pos
                    size: self.size
            cols: 1
            pos_hint: {"top":0.6, "left": 1}
            size_hint:1, .5

        Button:
            text: "New Screen"
            pos_hint: {"top":0.1, "left": 1}
            id: test
            size_hint:1, .1
            on_release:
                app.root.new_screen()

当我运行该应用程序时,最初一切似乎都很好。它将生成新屏幕。但是,我无法返回主页,因为这些按钮会生成“没有名称的屏幕”错误。

1 个答案:

答案 0 :(得分:0)

问题

  File "~/screenmanager.py", line 1064, in get_screen
     raise ScreenManagerException('No Screen with name "%s".' % name)
 kivy.uix.screenmanager.ScreenManagerException: No Screen with name "home_screen"

根本原因

在方法on_release()中,它实例化了MyScreenManager的另一个实例,该实例不同于在kv文件中实例化的实例。屏幕"home_screen""settings_screen"在此新的MyScreenManager实例中未定义。因此,您的Kivy应用抛出了ScreenManagerException

解决方案

在Python脚本中使用以下内容:

  1. App.get_running_app()函数可获取您的应用程序实例
  2. root引用当前规则中的基本小部件/模板

代码段-py文件

class MyButton(ButtonBehavior, Image):

    ...

    def on_release(self):
        App.get_running_app().root.current = "home_screen"
        self.source = "img/settings.png"
...
class MyGrids(GridLayout):

    def __init__(self, **kwargs):
        super(MyGrids, self).__init__(**kwargs)
        self.cols = 1
        self.add_widget(MyButton(
            # on_release = sm.change_screen(name="home_screen")
        ))
        self.add_widget(Button(
            text="World 4"
            # on_release = sm.change_screen(name="home_screen")
        ))
...
class MyScreenManager(ScreenManager):

    ...

    def new_screen(self):
        name = "new_screen"

        # if new_screen does not exist
        if not (name in self.screen_names):
            mynewscreen = Newscreen(name=name)
            layout = MyGrids()
            mynewscreen.add_widget(layout)
            self.add_widget(mynewscreen)

        # switch screen
        self.current = name

输出

Add new screen Home Screen Switch to New Screen