Kivy 从屏幕管理器访问 class 属性
Kivy accessing class attributes from screen manager
我正在使用 python 和 kivy 制作一个简单的应用程序,但是当我为我的应用程序创建多屏幕时,我无法访问某些 class 的 class 属性。
我在使用屏幕管理器访问方法时遇到问题。
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
class MyGame(Widget):
def __init__(self, **kwargs):
super(MyGame, self).__init__(**kwargs)
def print_a_word(self):
print('a word')
class OptionWindow(Screen):
pass
class SecondWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file('screen_manager.kv')
class MyMainApp(App):
def build(self):
return kv
if __name__ == "__main__":
MyMainApp().run()
kivy 文件 (screen_manager.kv)
#:kivy 2.0.0
# File name: screen_manager.kv
#: import MyGame Widget
WindowManager:
OptionWindow:
SecondWindow:
<OptionWindow>:
name: "main"
GridLayout:
cols:1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: 0, 0
size: root.width, root.height
GridLayout:
rows: 5
padding: 50, 50
spacing: 20, 20
OptionBtn:
text: 'Americas'
on_release:
app.root.current = "second"
root.manager.transition.direction = "left"
<SecondWindow>:
name: "second"
MyGame
Button:
on_press: root.MyGame.print_a_word()
<OptionBtn@Button>
background_normal: 'Images/Other/white.png'
color: 0, 0, 0, 1
font_size: 20
canvas.after:
Color:
rgba: 0, 0, 0, 1
Line:
rectangle: self.x, self.y, self.size[0], self.size[1]
一切正常,直到我按下第二个 window 的按钮。我无法从 MyGame(Widget) 访问该方法。我得到'SecondWindow' object has no attribute 'MyGame'
这是一个更大问题的一部分,因为我制作此文件是为了解决我原来的问题,即...
我有一个大程序,其中有两个文件 main.py 和 my.kv,我想添加屏幕。在这个 main.py 中,一切都定义了一个 class 继承自 Widget 和构建方法 returns 一个 class 的实例。这就是我从上面制作文件的原因...这是为了了解我如何从小部件 class 访问。谢谢
我在这里修复了您的示例代码,现在可以访问和执行 MyGame() 对象中的 print_my_word() 方法,这应该足以让您挡路。
只有 kv 文件需要更改:
在“MyGame”对象中使用包含而不是导入:
#: 包含 MyGame
在 对象中实例化它。
为它添加了一个 id,以便能够访问它。
WindowManager:
OptionWindow:
SecondWindow:
<OptionWindow>:
name: "main"
GridLayout:
cols:1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: 0, 0
size: root.width, root.height
GridLayout:
rows: 5
padding: 50, 50
spacing: 20, 20
OptionBtn:
text: 'Americas'
on_release:
app.root.current = "second"
root.manager.transition.direction = "left"
<SecondWindow>:
name: "second"
MyGame:
id: my_game
Button:
on_press: my_game.print_a_word()
<OptionBtn@Button>
background_normal: 'Images/Other/white.png'
color: 0, 0, 0, 1
font_size: 20
canvas.after:
Color:
rgba: 0, 0, 0, 1
Line:
rectangle: self.x, self.y, self.size[0], self.size[1]
好的,下面的下一部分是更新以在第二条评论中回答您的问题。
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
class MyGame(Widget):
def __init__(self, **kwargs):
super(MyGame, self).__init__(**kwargs)
def print_a_word(self):
print('My Game: print method')
class OptionWindow(Screen):
pass
class SecondWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file('screen_manager.kv')
class MyMainApp(App):
def build(self):
self.my_game = MyGame() # <-- instantiated MyGame in the Main class to access it from any where
return kv
if __name__ == "__main__":
MyMainApp().run()
screen_manager.kv
WindowManager:
OptionWindow:
SecondWindow:
<OptionWindow>:
name: "main"
GridLayout:
cols:1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: 0, 0
size: root.width, root.height
GridLayout:
rows: 5
padding: 50, 50
spacing: 20, 20
OptionBtn:
text: 'Americas'
on_release:
app.root.current = "second"
root.manager.transition.direction = "left"
# ADDED EXTRA BUTTON TO SAMPLE ACCESSING MyGame OBJECT, FROM THIS CLASS
Button:
text: 'Access My Game Method'
on_release:
app.my_game.print_a_word() # <-- app can access main class attributes and methods
<SecondWindow>:
name: "second"
# USE A BOXLAYOUT TO LAYOUT THE BUTTONS
BoxLayout:
orientation: 'vertical'
spacing: 2
padding: 2
# ADDED BUTTON TO SAMPLE ACCESSING MyGame OBJECT
Button:
text: 'Access method from MyGame'
on_press: app.my_game.print_a_word() # <-- app can access main class attributes and methods
Button:
text: 'Return to Main'
on_press: app.root.current = "main"
<OptionBtn@Button>
background_normal: 'Images/Other/white.png'
color: 0, 0, 0, 1
font_size: 20
canvas.after:
Color:
rgba: 0, 0, 0, 1
Line:
rectangle: self.x, self.y, self.size[0], self.size[1]
我正在使用 python 和 kivy 制作一个简单的应用程序,但是当我为我的应用程序创建多屏幕时,我无法访问某些 class 的 class 属性。
我在使用屏幕管理器访问方法时遇到问题。
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
class MyGame(Widget):
def __init__(self, **kwargs):
super(MyGame, self).__init__(**kwargs)
def print_a_word(self):
print('a word')
class OptionWindow(Screen):
pass
class SecondWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file('screen_manager.kv')
class MyMainApp(App):
def build(self):
return kv
if __name__ == "__main__":
MyMainApp().run()
kivy 文件 (screen_manager.kv)
#:kivy 2.0.0
# File name: screen_manager.kv
#: import MyGame Widget
WindowManager:
OptionWindow:
SecondWindow:
<OptionWindow>:
name: "main"
GridLayout:
cols:1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: 0, 0
size: root.width, root.height
GridLayout:
rows: 5
padding: 50, 50
spacing: 20, 20
OptionBtn:
text: 'Americas'
on_release:
app.root.current = "second"
root.manager.transition.direction = "left"
<SecondWindow>:
name: "second"
MyGame
Button:
on_press: root.MyGame.print_a_word()
<OptionBtn@Button>
background_normal: 'Images/Other/white.png'
color: 0, 0, 0, 1
font_size: 20
canvas.after:
Color:
rgba: 0, 0, 0, 1
Line:
rectangle: self.x, self.y, self.size[0], self.size[1]
一切正常,直到我按下第二个 window 的按钮。我无法从 MyGame(Widget) 访问该方法。我得到'SecondWindow' object has no attribute 'MyGame'
这是一个更大问题的一部分,因为我制作此文件是为了解决我原来的问题,即... 我有一个大程序,其中有两个文件 main.py 和 my.kv,我想添加屏幕。在这个 main.py 中,一切都定义了一个 class 继承自 Widget 和构建方法 returns 一个 class 的实例。这就是我从上面制作文件的原因...这是为了了解我如何从小部件 class 访问。谢谢
我在这里修复了您的示例代码,现在可以访问和执行 MyGame() 对象中的 print_my_word() 方法,这应该足以让您挡路。
只有 kv 文件需要更改:
在“MyGame”对象中使用包含而不是导入:
#: 包含 MyGame
在
为它添加了一个 id,以便能够访问它。
WindowManager:
OptionWindow:
SecondWindow:
<OptionWindow>:
name: "main"
GridLayout:
cols:1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: 0, 0
size: root.width, root.height
GridLayout:
rows: 5
padding: 50, 50
spacing: 20, 20
OptionBtn:
text: 'Americas'
on_release:
app.root.current = "second"
root.manager.transition.direction = "left"
<SecondWindow>:
name: "second"
MyGame:
id: my_game
Button:
on_press: my_game.print_a_word()
<OptionBtn@Button>
background_normal: 'Images/Other/white.png'
color: 0, 0, 0, 1
font_size: 20
canvas.after:
Color:
rgba: 0, 0, 0, 1
Line:
rectangle: self.x, self.y, self.size[0], self.size[1]
好的,下面的下一部分是更新以在第二条评论中回答您的问题。
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
class MyGame(Widget):
def __init__(self, **kwargs):
super(MyGame, self).__init__(**kwargs)
def print_a_word(self):
print('My Game: print method')
class OptionWindow(Screen):
pass
class SecondWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file('screen_manager.kv')
class MyMainApp(App):
def build(self):
self.my_game = MyGame() # <-- instantiated MyGame in the Main class to access it from any where
return kv
if __name__ == "__main__":
MyMainApp().run()
screen_manager.kv
WindowManager:
OptionWindow:
SecondWindow:
<OptionWindow>:
name: "main"
GridLayout:
cols:1
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: 0, 0
size: root.width, root.height
GridLayout:
rows: 5
padding: 50, 50
spacing: 20, 20
OptionBtn:
text: 'Americas'
on_release:
app.root.current = "second"
root.manager.transition.direction = "left"
# ADDED EXTRA BUTTON TO SAMPLE ACCESSING MyGame OBJECT, FROM THIS CLASS
Button:
text: 'Access My Game Method'
on_release:
app.my_game.print_a_word() # <-- app can access main class attributes and methods
<SecondWindow>:
name: "second"
# USE A BOXLAYOUT TO LAYOUT THE BUTTONS
BoxLayout:
orientation: 'vertical'
spacing: 2
padding: 2
# ADDED BUTTON TO SAMPLE ACCESSING MyGame OBJECT
Button:
text: 'Access method from MyGame'
on_press: app.my_game.print_a_word() # <-- app can access main class attributes and methods
Button:
text: 'Return to Main'
on_press: app.root.current = "main"
<OptionBtn@Button>
background_normal: 'Images/Other/white.png'
color: 0, 0, 0, 1
font_size: 20
canvas.after:
Color:
rgba: 0, 0, 0, 1
Line:
rectangle: self.x, self.y, self.size[0], self.size[1]