Мой экранный менеджер не возвращается на домашний экран - PullRequest
2 голосов
/ 06 июля 2019

Привет, я новичок в 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:

<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 голосов
/ 07 июля 2019

Проблема

  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.

Solution

Используйте в скрипте 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...