您好,我是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()
当我运行该应用程序时,最初一切似乎都很好。它将生成新屏幕。但是,我无法返回主页,因为这些按钮会生成“没有名称的屏幕”错误。
答案 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脚本中使用以下内容:
App.get_running_app()
函数可获取您的应用程序实例root
引用当前规则中的基本小部件/模板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